Exemple #1
0
    def __init__(self,
                 cube,
                 wcs=None,
                 mask=None,
                 sigma=None,
                 empty_channel=0,
                 keep_threshold_mask=True,
                 distance=None,
                 galaxy_props={}):
        super(BubbleFinder, self).__init__()

        if not isinstance(cube, SpectralCube):
            if wcs is None:
                raise TypeError("When cube is not a SpectralCube, wcs must be"
                                " given.")
            cube = SpectralCube(cube, wcs)
            if mask is not None:
                cube = cube.with_mask(mask)

        self.cube = cube

        self.empty_channel = empty_channel

        if sigma is None:
            self.estimate_sigma()
        else:
            self.sigma = sigma

        self.keep_threshold_mask = keep_threshold_mask
        self._mask = None
        self.distance = distance
        self.galaxy_props = galaxy_props
Exemple #2
0
    def __init__(self, cube, wcs=None, mask=None, sigma=None, empty_channel=0,
                 keep_threshold_mask=True, distance=None, galaxy_props={}):
        super(BubbleFinder, self).__init__()

        if not isinstance(cube, SpectralCube):
            if wcs is None:
                raise TypeError("When cube is not a SpectralCube, wcs must be"
                                " given.")
            cube = SpectralCube(cube, wcs)
            if mask is not None:
                cube = cube.with_mask(mask)

        self.cube = cube

        self.empty_channel = empty_channel

        if sigma is None:
            self.estimate_sigma()
        else:
            self.sigma = sigma

        self.keep_threshold_mask = keep_threshold_mask
        self._mask = None
        self.distance = distance
        self.galaxy_props = galaxy_props
Exemple #3
0
    def _spectrum_from_component(self, layer, component, wcs, mask=None):
        data = SpectralCube(component.data, wcs)

        if mask is not None:
            data = data.with_mask(mask)

        if self._data_operation.currentIndex() == 1:
            spec_data = data.mean((1, 2))
        elif self._data_operation.currentIndex() == 2:
            spec_data = data.median((1, 2))
        else:
            spec_data = data.sum((1, 2))

        spec_data = Spectrum1DRef(spec_data.data,
                                  unit=spec_data.unit,
                                  dispersion=data.spectral_axis.data,
                                  dispersion_unit=data.spectral_axis.unit,
                                  wcs=data.wcs,
                                  name=layer.label)

        # Store the relation between the component and the specviz data. If
        # the data exists, first remove the component from specviz and then
        # re-add it.
        if layer in self._specviz_data_cache:
            old_spec_data = self._specviz_data_cache[layer]
            dispatch.on_remove_data.emit(old_spec_data)

        self._specviz_data_cache[layer] = spec_data

        dispatch.on_add_to_window.emit(data=spec_data,
                                       style={'color': layer.style.rgba[:3]})
def load_and_reduce(filename, add_noise=False, rms_noise=0.001,
                    nsig=3):
    '''
    Load the cube in and derive the property arrays.
    '''

    if add_noise:
        if rms_noise is None:
            raise TypeError("Must specify value of rms noise.")

        cube, hdr = getdata(filename, header=True)

        from scipy.stats import norm
        cube += norm.rvs(0.0, rms_noise, cube.shape)

        sc = SpectralCube(data=cube, wcs=WCS(hdr))

        mask = LazyMask(np.isfinite, sc)
        sc = sc.with_mask(mask)

    else:
        sc = filename

    reduc = Mask_and_Moments(sc, scale=rms_noise)
    reduc.make_mask(mask=reduc.cube > nsig * reduc.scale)
    reduc.make_moments()
    reduc.make_moment_errors()

    return reduc.to_dict()
Exemple #5
0
    def _spectrum_from_component(self,
                                 layer,
                                 component,
                                 wcs,
                                 mask=None,
                                 cid=None):
        data = SpectralCube(component.data, wcs)

        if mask is not None:
            data = data.with_mask(mask)

        # Update the associated data attribute in the plugin
        self._spec_ops.spectral_data = data
        self._spec_ops.component_id = cid

        if self._data_operation.currentIndex() == 1:
            spec_data = data.mean((1, 2))
        elif self._data_operation.currentIndex() == 2:
            spec_data = data.median((1, 2))
        else:
            spec_data = data.sum((1, 2))

        spec_data = Spectrum1DRef(spec_data.data,
                                  unit=spec_data.unit,
                                  dispersion=data.spectral_axis.data,
                                  dispersion_unit=data.spectral_axis.unit,
                                  wcs=data.wcs,
                                  name=layer.label)

        spec_layer = Spectrum1DRefLayer.from_parent(spec_data)

        # Store the relation between the component and the specviz data. If
        # the data exists, first remove the component from specviz and then
        # re-add it.
        old_spec_layer = self._specviz_data_cache.get(layer)

        self._specviz_data_cache[layer] = spec_layer

        if old_spec_layer is None:
            dispatch.on_add_to_window.emit(layer=spec_layer,
                                           style={
                                               'color': layer.style.rgba[:3],
                                               'line_width': 3
                                           },
                                           vertical_line=True)
        else:
            dispatch.replace_layer.emit(old_layer=old_spec_layer,
                                        new_layer=spec_layer,
                                        style={
                                            'color': layer.style.rgba[:3],
                                            'line_width': 3
                                        })
def reduce_and_save(filename, add_noise=False, rms_noise=0.001,
                    output_path="", cube_output=None,
                    nsig=3, slicewise_noise=True):
    '''
    Load the cube in and derive the property arrays.
    '''

    if add_noise:
        if rms_noise is None:
            raise TypeError("Must specify value of rms noise.")

        cube, hdr = getdata(filename, header=True)

        # Optionally scale noise by 1/10th of the 98th percentile in the cube
        if rms_noise == 'scaled':
            rms_noise = 0.1*np.percentile(cube[np.isfinite(cube)], 98)

        from scipy.stats import norm
        if not slicewise_noise:
            cube += norm.rvs(0.0, rms_noise, cube.shape)
        else:
            spec_shape = cube.shape[0]
            slice_shape = cube.shape[1:]
            for i in range(spec_shape):
                cube[i, :, :] += norm.rvs(0.0, rms_noise, slice_shape)

        sc = SpectralCube(data=cube, wcs=WCS(hdr))

        mask = LazyMask(np.isfinite, sc)
        sc = sc.with_mask(mask)

    else:
        sc = filename

    reduc = Mask_and_Moments(sc, scale=rms_noise)
    reduc.make_mask(mask=reduc.cube > nsig * reduc.scale)

    reduc.make_moments()
    reduc.make_moment_errors()

    # Remove .fits from filename
    save_name = filename.split("/")[-1][:-4]

    reduc.to_fits(output_path+save_name)

    # Save the noisy cube too
    if add_noise:
        if cube_output is None:
            reduc.cube.hdu.writeto(output_path+save_name)
        else:
            reduc.cube.hdu.writeto(cube_output+save_name)
Exemple #7
0
def warp_ellipse_to_circle(cube, a, b, pa, stop_if_huge=True):
    '''
    Warp a SpectralCube such that the given ellipse is a circle int the
    warped frame.

    Since you should **NOT** be doing this with a large cube, we're going
    to assume that the given cube is a subcube centered in the middle of the
    cube.

    This requires a rotation, then scaling. The equivalent matrix is:
    [b cos PA    b sin PA]
    [-a sin PA   a cos PA ].

    '''

    if cube._is_huge:
        if stop_if_huge:
            raise Warning("The cube has the huge flag enabled. Disable "
                          "'stop_if_huge' if you would like to continue "
                          "anyways with the warp.")
        else:
            warn("The cube has the huge flag enabled. This may use a lot "
                 "of memory!")

    # Let NaNs be 0
    data = cube.with_fill_value(0.0).filled_data[:].value

    warped_array = []

    for i in range(cube.shape[0]):
        warped_array.append(
            nd.zoom(nd.rotate(data[i], np.rad2deg(-pa)), (1, a / b)))

    warped_array = np.array(warped_array)

    # We want to mask outside of the original bounds
    mask = np.ones(data.shape[1:])
    warp_mask = \
        np.isclose(nd.zoom(nd.rotate(mask, np.rad2deg(-pa)),
                           (1, a / b)), 1)

    # There's probably a clever way to transform the WCS, but all the
    # solutions appear to need pyast/starlink. The output of the wrap should
    # give a radius of b and the spectral dimension is unaffected.
    # Also this is hidden and users won't be able to use this weird cube
    # directly
    warped_cube = SpectralCube(warped_array * cube.unit, cube.wcs)
    warped_cube = warped_cube.with_mask(warp_mask)

    return warped_cube
Exemple #8
0
def warp_ellipse_to_circle(cube, a, b, pa, stop_if_huge=True):
    '''
    Warp a SpectralCube such that the given ellipse is a circle int the
    warped frame.

    Since you should **NOT** be doing this with a large cube, we're going
    to assume that the given cube is a subcube centered in the middle of the
    cube.

    This requires a rotation, then scaling. The equivalent matrix is:
    [b cos PA    b sin PA]
    [-a sin PA   a cos PA ].

    '''

    if cube._is_huge:
        if stop_if_huge:
            raise Warning("The cube has the huge flag enabled. Disable "
                          "'stop_if_huge' if you would like to continue "
                          "anyways with the warp.")
        else:
            warn("The cube has the huge flag enabled. This may use a lot "
                 "of memory!")

    # Let NaNs be 0
    data = cube.with_fill_value(0.0).filled_data[:].value

    warped_array = []

    for i in range(cube.shape[0]):
        warped_array.append(nd.zoom(nd.rotate(data[i], np.rad2deg(-pa)),
                                    (1, a / b)))

    warped_array = np.array(warped_array)

    # We want to mask outside of the original bounds
    mask = np.ones(data.shape[1:])
    warp_mask = \
        np.isclose(nd.zoom(nd.rotate(mask, np.rad2deg(-pa)),
                           (1, a / b)), 1)

    # There's probably a clever way to transform the WCS, but all the
    # solutions appear to need pyast/starlink. The output of the wrap should
    # give a radius of b and the spectral dimension is unaffected.
    # Also this is hidden and users won't be able to use this weird cube
    # directly
    warped_cube = SpectralCube(warped_array * cube.unit, cube.wcs)
    warped_cube = warped_cube.with_mask(warp_mask)

    return warped_cube
Exemple #9
0
def get_best_2comp_residual_cnv(reg, masked=True, window_hwidth=3.5, res_snr_cut=5):
    # return convolved residual cube. If masked is True, only convolve over where 'excessive' residual
    # above a peak SNR value of res_snr_cut masked

    # need a mechanism to make sure reg.ucube.pcubes['1'], reg.ucube.pcubes['2'] exists

    res_cube = get_best_2comp_residual(reg)
    best_res = res_cube._data
    cube_res = SpectralCube(data=best_res, wcs=reg.ucube.pcubes['2'].wcs.copy(),
                            header=reg.ucube.pcubes['2'].header.copy())

    if masked:
        best_rms = UCube.get_rms(res_cube._data)

        # calculate the peak SNR value of the best-fit residual over the main hyperfine components
        vmap = reg.ucube.pcubes['1'].parcube[0]
        # make want to double check that masked cube always masks out nan values
        res_main_hf = mmg.vmask_cube(res_cube, vmap, window_hwidth=window_hwidth)

        if res_main_hf.size > 1e7:
            # to avoid loading entire cube and stress the memory
            how = 'slice'
        else:
            # note: 'auto' currently returns slice for n > 1e8
            how = 'auto'

        # enable huge operations (note: not needed when "how" is chosen wisely, which it should be)
        res_main_hf.allow_huge_operations = True
        res_main_hf_snr = res_main_hf.max(axis=0, how=how).value / best_rms
        res_main_hf.allow_huge_operations = False

        # mask out residual with SNR values over the cut threshold
        mask_res = res_main_hf_snr > res_snr_cut
        mask_res = dilation(mask_res)

        cube_res_masked = cube_res.with_mask(~mask_res)
    else:
        cube_res_masked = cube_res

    cube_res_cnv = cnvtool.convolve_sky_byfactor(cube_res_masked, factor=reg.cnv_factor, edgetrim_width=None,
                                                 snrmasked=False, iterrefine=False)

    cube_res_cnv = cube_res_cnv.with_spectral_unit(u.km / u.s, velocity_convention='radio')
    return cube_res_cnv
Exemple #10
0
def load_and_reduce(filename,
                    add_noise=False,
                    rms_noise=0.001,
                    nsig=3,
                    slicewise_noise=True):
    '''
    Load the cube in and derive the property arrays.
    '''

    if add_noise:
        if rms_noise is None:
            raise TypeError("Must specify value of rms noise.")

        cube, hdr = getdata(filename, header=True)

        # Optionally scale noise by 1/10th of the 98th percentile in the cube
        if rms_noise == 'scaled':
            rms_noise = 0.1 * np.percentile(cube[np.isfinite(cube)], 98)

        from scipy.stats import norm
        if not slicewise_noise:
            cube += norm.rvs(0.0, rms_noise, cube.shape)
        else:
            spec_shape = cube.shape[0]
            slice_shape = cube.shape[1:]
            for i in range(spec_shape):
                cube[i, :, :] += norm.rvs(0.0, rms_noise, slice_shape)

        sc = SpectralCube(data=cube, wcs=WCS(hdr))

        mask = LazyMask(np.isfinite, sc)
        sc = sc.with_mask(mask)

    else:
        sc = filename

    reduc = Mask_and_Moments(sc, scale=rms_noise)
    reduc.make_mask(mask=reduc.cube > nsig * reduc.scale)
    reduc.make_moments()
    reduc.make_moment_errors()

    return reduc.to_dict()
def load_and_reduce(filename, add_noise=False, rms_noise=0.001,
                    nsig=3, slicewise_noise=True):
    '''
    Load the cube in and derive the property arrays.
    '''

    if add_noise:
        if rms_noise is None:
            raise TypeError("Must specify value of rms noise.")

        cube, hdr = getdata(filename, header=True)

        # Optionally scale noise by 1/10th of the 98th percentile in the cube
        if rms_noise == 'scaled':
            rms_noise = 0.1*np.percentile(cube[np.isfinite(cube)], 98)

        from scipy.stats import norm
        if not slicewise_noise:
            cube += norm.rvs(0.0, rms_noise, cube.shape)
        else:
            spec_shape = cube.shape[0]
            slice_shape = cube.shape[1:]
            for i in range(spec_shape):
                cube[i, :, :] += norm.rvs(0.0, rms_noise, slice_shape)

        sc = SpectralCube(data=cube, wcs=WCS(hdr))

        mask = LazyMask(np.isfinite, sc)
        sc = sc.with_mask(mask)

    else:
        sc = filename

    reduc = Mask_and_Moments(sc, scale=rms_noise)
    reduc.make_mask(mask=reduc.cube > nsig * reduc.scale)
    reduc.make_moments()
    reduc.make_moment_errors()

    return reduc.to_dict()
Exemple #12
0
    def _spectrum_from_component(self, layer, component, wcs, mask=None):
        data = SpectralCube(component.data, wcs)

        if mask is not None:
            data = data.with_mask(mask)

        spec_data = data.sum((1, 2))

        spec_data = Spectrum1DRef(spec_data.data,
                                  unit=spec_data.unit,
                                  dispersion=data.spectral_axis.data,
                                  dispersion_unit=data.spectral_axis.unit,
                                  wcs=data.wcs)

        # Store the relation between the component and the specviz data. If
        # the data exists, first remove the component from specviz and then
        # re-add it.
        if layer in self._specviz_data_cache:
            old_spec_data = self._specviz_data_cache[layer]
            dispatch.on_remove_data.emit(old_spec_data)

        self._specviz_data_cache[layer] = spec_data

        dispatch.on_add_to_window.emit(spec_data)
Exemple #13
0
def calc_structure_fcn(catalog,
                       bootiter=0,doPlot=False):
    
    cat = catalog
    if 'sf_offset' not in cat.keys():
        keylist = ['sf_offset','sf_index','sf_ngood',
                   'sf_index_err','sf_offset_err', 'vca_index',
                   'vca_index_err']
        for thiskey in keylist:
            c = Column(np.zeros(len(cat))+np.nan,name=thiskey)
            cat.add_column(c)
        
    current_open_file = ''
    for cloud in cat:
        root = cloud['orig_file'].split('_')
        orig_file = 'COHRS_{0}_{1}.fits'.format(root[-2], root[-1])
        asgn_file = cloud['orig_file'] + '_fasgn.fits'
        if os.path.isfile(datadir+'COHRS_tiles/'+orig_file):
            if current_open_file != datadir+'COHRS_tiles/'+orig_file:
                hdu = fits.open(datadir+'COHRS_tiles/'+orig_file,memmap=False)
                cat.write('cohrs_structurefunc.fits',overwrite=True)
                w = wcs.WCS(hdu[0].header)
                hdr2 = w.to_header()
                hdr2['BMAJ'] = 15./3600
                hdr2['BMIN'] = 15./3600
                hdr2['BPA'] = 0.
                co = SpectralCube(hdu[0].data,w,header=hdr2)
                hdu = fits.open(datadir+'ASGN/'+asgn_file,memmap=False)
                w = wcs.WCS(hdu[0].header)
                hdr2 = w.to_header()
                hdr2['BMAJ'] = 15./3600
                hdr2['BMIN'] = 15./3600
                hdr2['BPA'] = 0.
                asgn = SpectralCube(hdu[0].data,w,header=hdr2)

#                masked_co = co.with_mask(asgn>0*u.dimensionless_unscaled)
#                moment = masked_co.moment(0)
                
                current_open_file = datadir+'COHRS_tiles/'+orig_file

            print(cloud['cloud_id'])
            mask = (asgn == cloud['cloud_id']*u.dimensionless_unscaled)
            subcube = co.with_mask(mask)
            subcube = subcube.subcube_from_mask(mask)
#            subcube.moment0().quicklook()
#            plt.show()
            if subcube.shape[0] > 10:
                # zeros = np.zeros_like(subcube) # np.random.randn(*subcube.shape)*0.5
                # concatdata = np.vstack([subcube.filled_data[:],zeros])
                # hdr2 = subcube.wcs.to_header()
                # hdr2['BMAJ'] = 15./3600
                # hdr2['BMIN'] = 15./3600
                # hdr2['BPA'] = 0.
                # newcube = SpectralCube(concatdata,subcube.wcs,header=hdr2)
                # if True:
                try:
                    pcaobj = pca.PCA(subcube,
                                     distance=cloud['bgps_distance_pc']*u.pc)
                    vcaobj = vca.VCA(subcube,
                                     distance=cloud['bgps_distance_pc']*u.pc)
                    vcaobj.run(verbose=False, high_cut = 0.3/u.pix)
                    pcaobj.run(verbose=True,mean_sub=True,
                               min_eigval=0.9,eigen_cut_method='proportion')
                    cloud['sf_index']= pcaobj.index
                    cloud['sf_offset'] = pcaobj.intercept.value
                    cloud['sf_ngood'] = np.min([np.isfinite(pcaobj.spatial_width).sum(),
                                                np.isfinite(pcaobj.spectral_width).sum()])
                    
                    cloud['sf_index_err'] = (pcaobj.index_error_range[1]-pcaobj.index_error_range[0])*0.5
                    cloud['sf_offset_err'] = ((pcaobj.intercept_error_range[1]-pcaobj.intercept_error_range[0])*0.5).value
                    cloud['vca_index'] = vcaobj.slope
                    cloud['vca_index_err'] = vcaobj.slope_err
                    print('{0} +/- {1}'.format(cloud['sf_index'],
                                               cloud['sf_index_err']),
                          cloud['sf_offset'])
                    # import pdb; pdb.set_trace()
                # else:
                except:
                    pass
        
    cat.write('output_catalog2.fits',overwrite=True)
#    88.63185 GHz (0.48257208, 0.0)
#    88.63394 GHz (0.3509686, 0.0)
#    88.6316024 GHz (0.49761587, 0.0)

from FITS_tools import regrid_cube
hnc_regrid = regrid_cube(cubehnc.filled_data[:], cubehnc.header, cubehcn.header)
cubehnc = SpectralCube(data=hnc_regrid, wcs=cubehcn.wcs)

#cubehnc._wcs = cubehcn.wcs
#cubehnc.mask._wcs = cubehcn.wcs

mask  = (cubehcn > 0.5)
mask2 = (cubehcn > 0.5)
#mask2._wcs = cubehnc.wcs
hcn_flat = cubehcn.with_mask(mask).flattened()
hnc_flat = cubehnc.with_mask(mask2).flattened()

mask3 = cubehnc > 0.5
mask4 = cubehnc > 0.5
#mask4._wcs = cubehcn.wcs
hnc_flat2 = cubehnc.with_mask(mask3).flattened()
hcn_flat2 = cubehcn.with_mask(mask4).flattened()

import pylab as pl
pl.clf()
pl.plot(hnc_flat, hcn_flat, ',', alpha=0.5)
pl.plot(hnc_flat2, hcn_flat2, ',', alpha=0.5)
pl.plot([0,5],[0,5],'k--')
pl.axis([0,5,0,5])

dd = cubehcn.to_ds9()
Exemple #15
0
dataset1 = np.load(path1)

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

count = 0
for posn, kept in zip(*dataset1["channels"]):
    posn = int(posn)
    if kept:
        cube1[posn, :, :] = dataset1["cube"][count, :, :]
        count += 1
    else:
        cube1[posn, :, :] = ra.normal(0.005, 0.005, (32, 32))

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)

##############################################################################
    denscube = denscube.with_mask(okmask)
    colcube  = SpectralCube.read(paths.dpath("H2CO_ParameterFits_{0}col.fits".format(meastype)))
    colcube = colcube.with_mask(okmask)
    goodmask_std = stdcube < 0.5

    flathead = denscube.wcs.dropaxis(2).to_header()

    denscube_lin = SpectralCube(10**denscube.filled_data[:].value,
                                              wcs=denscube.wcs,
                                              mask=okmask)
    colcube_lin = SpectralCube(10**colcube.filled_data[:].value,
                                             wcs=denscube.wcs, mask=okmask)


    totalcol = colcube_lin.sum(axis=0)
    totalcolgood = colcube_lin.with_mask(goodmask).sum(axis=0)
    totalcolgoodstd = colcube_lin.with_mask(goodmask_std).sum(axis=0)

    denscol = SpectralCube(denscube_lin.filled_data[:] * colcube_lin.filled_data[:], wcs=denscube.wcs,
                                         mask=okmask)
    wtdmeandens = np.log10(denscol.sum(axis=0) / totalcol)

    mindens_std = denscube.with_mask(goodmask_std).min(axis=0)
    mindens_chi2 = denscube.with_mask(goodmask).min(axis=0)

    hdu1 = fits.PrimaryHDU(data=wtdmeandens.value,
                           header=flathead)
    hdu1.writeto(paths.dpath("H2CO_ParameterFits_weighted_mean_{0}_density.fits".format(meastype)), clobber=True)

    masked_wtdmeans = np.log10(denscol.with_mask(goodmask).sum(axis=0) / totalcolgood)
    hdu2 = fits.PrimaryHDU(data=masked_wtdmeans.value,
Exemple #17
0
def calc_irlum(catalog = 'cohrs_finalcatalog_clumpflux_medaxis.fits',
               refresh=False):
    ctrr = 0
    cat = Table.read(catalog)
    current_open_file = ''
    if 'ir_luminosity' not in cat.keys():
        keylist = ['ir_luminosity','ir_flux','ir_flux_short',
                'ir_lum_short','bg_flux','bg_lum']
        for thiskey in keylist:
            c = Column(np.zeros(len(cat))+np.nan,name=thiskey)
            cat.add_column(c)

    for cloud in cat:
        if np.isnan(cloud['ir_luminosity']) or refresh:
            orig_file = cloud['orig_file']+'.fits'
            asgn_file = cloud['orig_file']+'_fasgn.fits'
            higal_file = orig_file.replace('cohrs','higal_xmatch')
            if os.path.isfile(datadir+'COHRS/'+orig_file) and \
                    os.path.isfile(datadir+'HIGAL_MATCHED/'+higal_file):
                if current_open_file != datadir+'COHRS/'+orig_file:
                    hdu = fits.open(datadir+'COHRS/'+orig_file,memmap=False)
                    w = wcs.WCS(hdu[0].header)
                    hdr2 = w.to_header()
                    hdr2['BMAJ'] = 15./3600
                    hdr2['BMIN'] = 15./3600
                    hdr2['BPA'] = 0.
                    co = SpectralCube(hdu[0].data,w,header=hdr2)
                    irfull= fits.open(datadir+'HIGAL_MATCHED/'+higal_file,memmap=False)
                    irlong = fits.open(datadir+'HIGAL_MATCHED2/'+higal_file,memmap=False)
                    irmap = (irfull[0].data-irlong[0].data)
                    irmap2 = irfull[0].data
                    asgn = fits.getdata(datadir+'ASSIGNMENTS/'+asgn_file,memmap=False)
                    masked_co = co.with_mask(asgn>0*u.dimensionless_unscaled)
                    moment = masked_co.moment(0)
                    current_open_file = datadir+'COHRS/'+orig_file
                    cat.write('output_catalog.fits',overwrite=True)
#                mask = np.zeros(co.shape,dtype=np.bool)
#                mask[asgn == cloud['cloud_id']]=True
                cloud_cube = co.with_mask(asgn == cloud['cloud_id'])
                cloud_moment = cloud_cube.moment(0)
                cloud_cube = 0.0
                fraction = (cloud_moment.value/moment.value)
                planemask = skm.binary_closing(fraction > 0,selem=skm.disk(3))
                fraction = np.nanmean(fraction)
                rind = (skm.binary_dilation(planemask,selem=skm.disk(6)) ^\
                        skm.binary_dilation(planemask,selem=skm.disk(3)))*\
                    np.isfinite(irmap2)
                if np.any(rind):
                    rindvals = irmap2[rind]
                    clipval = 4*np.percentile(rindvals,15.87)-\
                              3*(np.percentile(rindvals,2.28))
                    rind *= irmap2 <= clipval
                    yv,xv = np.where(rind)
                    x0,y0 = np.median(xv),np.median(yv)
                    dataz = np.c_[np.ones(xv.size), 
                                  xv-x0, 
                                  yv-y0]
                    try:

                        lsqcoeffs,_,_,_ = np.linalg.lstsq(dataz,irmap2[rind])
                        outputs = lsq(myplane,np.r_[lsqcoeffs,0],
                                     args=(xv-x0,
                                           yv-y0,
                                           irmap2[rind]),
                                     loss = 'soft_l1')
                        coeffs = outputs.x
                        yhit,xhit = np.where(planemask)
                        bg = coeffs[0]+coeffs[1]*(xhit-x0)+\
                             coeffs[2]*(yhit-y0)+coeffs[3]*(yhit-y0)*(xhit-x0)

                        # I am sitcking a 6e11 in here as the frequency of 
                        # the 500 microns
                        bgavg = np.sum(fraction*bg)/6e11
                        bglum = bgavg*cloud['distance']**2*\
                                3.086e18**2*np.pi*4/3.84e33

                    except ValueError:
                        import pdb; pdb.set_trace()


                    ir_flux = np.nansum(fraction*(irmap[planemask]))/6e11
                    ir_lum = ir_flux * cloud['distance']**2*\
                             3.086e18**2*np.pi*4/3.84e33
                    ir_flux2 = np.nansum(fraction*irmap2[planemask])/6e11
                    ir_lum2 = ir_flux2 * cloud['distance']**2*\
                             3.086e18**2*np.pi*4/3.84e33
                    cloud['ir_flux'] = ir_flux2
                    cloud['ir_luminosity'] = ir_lum2
                    cloud['ir_flux_short'] = ir_flux
                    cloud['ir_lum_short'] = ir_lum
                    cloud['bg_flux'] = bgavg
                    cloud['bg_lum'] = bglum
                    print(cloud['cloud_id'],ir_flux,ir_lum,ir_lum2,bglum)
                    cat.write('output_catalog.fits',overwrite=True)
                    ctrr+=1
                    if ctrr==20:
                        return(cat)
    #                if cloud['volume_pc2_kms']>1e2:
    #                    import pdb; pdb.set_trace()
    
    return(cat)
def smooth_cube(
        incube=None,
        outfile=None,
        angular_resolution=None,
        linear_resolution=None,
        distance=None,
        velocity_resolution=None,
        nan_treatment='interpolate', # can also be 'fill'
        tol=None,
        make_coverage_cube=False,
        collapse_coverage=False,
        coveragefile=None,
        coverage2dfile=None,
        dtype=np.float32,
        overwrite=True
    ):
    """
    Smooth an input cube to coarser angular or spectral
    resolution. This lightly wraps spectral cube and some of the error
    checking is left to that.

    tol is a fraction. When the target beam is within tol of the
    original beam, we just copy.

    Optionally, also calculate a coverage footprint in which original
    (finite) cube coverage starts at 1.0 and the output cube shows the
    fraction of finite pixels.
    """

    # &%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%
    # Error checking
    # &%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%

    # Require a valid cube or map input
    if type(incube) is SpectralCube:
        cube = incube
    elif type(incube) == type("hello"):
        cube = SpectralCube.read(incube)
    else:
        logger.error("Input must be a SpectralCube object or a filename.")

    # Allow huge operations. If the speed or segfaults become a huge
    # problem, we will adjust our strategy here.

    cube.allow_huge_operations = True

    # Check that only one target scale is set
    if (angular_resolution is not None) and (linear_resolution is not None):
        logger.error('Only one of angular_resolution or ',
                     'linear_resolution can be set')
        return(None)

    # Work out the target angular resolution
    if angular_resolution is not None:
        if type(angular_resolution) is str:
            angular_resolution = u.Quantity(angular_resolution)

    if linear_resolution is not None:
        if distance is None:
            logger.error('Convolution to linear resolution requires a distance.')
            return(None)

        if type(distance) is str:
            distance = u.Quantity(distance)
        if type(linear_resolution) is str:
            linear_resolution = u.Quantity(linear_resolution)
        angular_resolution = (linear_resolution / distance * u.rad).to(u.arcsec)
        dist_mpc_val = float(distance.to(u.pc).value) / 1e6
        cube._header.append(('DIST_MPC',dist_mpc_val,'Used in convolution'))

    if tol is None:
        tol = 0.0

    # &%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%
    # Convolution to coarser beam
    # &%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%
    
    if angular_resolution is not None:
        logger.info("... convolving from beam: "+str(cube.beam))
        target_beam = Beam(major=angular_resolution,
                           minor=angular_resolution,
                           pa=0 * u.deg)
        logger.info("... convolving to beam: "+str(target_beam))

        new_major = float(target_beam.major.to(u.arcsec).value)
        old_major = float(cube.beam.major.to(u.arcsec).value)        
        delta = (new_major-old_major)/old_major

        logger.info("... fractional change: "+str(delta))
        
        if make_coverage_cube:
            coverage = SpectralCube(np.isfinite(cube.unmasked_data[:])*1.0,
                                    wcs=cube.wcs,
                                    header=cube.header,
                                    meta={'BUNIT': ' ', 'BTYPE': 'Coverage'})
            coverage = coverage.with_mask(LazyMask(np.isfinite,cube=coverage))
            
            # Allow huge operations. If the speed or segfaults become a huge
            # problem, we will adjust our strategy here.

            coverage.allow_huge_operations = True

        if delta > tol:
            logger.info("... proceeding with convolution.")
            cube = cube.convolve_to(target_beam,
                                    nan_treatment=nan_treatment)
            if make_coverage_cube:
                coverage = coverage.convolve_to(target_beam,
                                                nan_treatment=nan_treatment)

        if np.abs(delta) < tol:
            logger.info("... current resolution meets tolerance.")

        if delta < -1.0*tol:
            logger.info("... resolution cannot be matched. Returning")
            return(None)

    # &%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%
    # Spectral convolution
    # &%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%

    # This is only a boxcar smooth right now and does not downsample
    # or update the header.

    if velocity_resolution is not None:
        if type(velocity_resolution) is str:
            velocity_resolution = u.Quantity(velocity_resolution)

        dv = scdr.channel_width(cube)
        nChan = (velocity_resolution / dv).to(u.dimensionless_unscaled).value
        if nChan > 1:
            cube = cube.spectral_smooth(Box1DKernel(nChan))
            if make_coverage_cube:
                coverage = coverage.spectral_smooth(Box1DKernel(nChan))

    # &%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%
    # Write or return as requested
    # &%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%

    if outfile is not None:
        # cube.write(outfile, overwrite=overwrite)
        hdu = fits.PrimaryHDU(np.array(cube.filled_data[:], dtype=dtype),
                              header=cube.header)
        hdu.writeto(outfile, overwrite=overwrite)
        if make_coverage_cube:
            if coveragefile is not None:
                hdu = fits.PrimaryHDU(np.array(coverage.filled_data[:], dtype=dtype),
                                      header=coverage.header)
                hdu.writeto(coveragefile, overwrite=overwrite)
            if collapse_coverage:
                if coveragefile and not coverage2dfile:
                    coverage2dfile = coveragefile.replace('.fits','2d.fits')
                coverage_collapser(coverage,
                                   coverage2dfile=coverage2dfile,
                                   overwrite=overwrite)
                # coverage.write(coveragefile, overwrite=overwrite)

    return(cube)
Exemple #19
0
dataset1 = np.load(path1)

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

count = 0
for posn, kept in zip(*dataset1["channels"]):
    posn = int(posn)
    if kept:
        cube1[posn, :, :] = dataset1["cube"][count, :, :]
        count += 1
    else:
        cube1[posn, :, :] = ra.normal(0.005, 0.005, (32, 32))

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)

##############################################################################
Exemple #20
0
def common_cube(filename,
                target_rms=None,
                target_resolution=None,
                datadir='',
                outdir='',
                outname='common.fits',
                cube=None,
                rmsname=None,
                rmsmap=None,
                distance=None,
                overwrite=True,
                return_cube=False,
                huge=True):
    """
        Convolves and adds noise to a data cube to arrive at 
        a target linear resolution and noise level
        
        Parameters:
        
        filename : str
            File name of spectral data cube to process
    
        outname : str
            File name for output cube
            
        target_rms : astropy.Quantity
            Target RMS level in units of cube brightness
            
        target_resolution : astropy.Quantity
            Target resolution expressed as either length (linear 
            resolution) or angle (angular resolution) 
            
        datadir : str
            Directory for input data
        
        outdir : str
            Directory for output data
        
        rmsname : str
            Name for input RMS data cube
        
        rmsmap : np.ndarray
            numpy array of noise values at positions corresponding to 
            the spectral cube.
        
        distance : astropy.Quantity
            Distance to target; required if a linear target 
            resolution is requested
            
        overwrite : bool
            Overwrite output products if they already exist?
        
        return_cube : bool
            Return a SpectralCube?
        """

    if cube is None:
        cube = SpectralCube.read(os.path.join(datadir, filename))

    cube.allow_huge_operations = huge
    orig_beam_area = cube.beam.sr
    target_beam = None
    if target_resolution is not None:
        if target_resolution.unit.is_equivalent(u.pc):
            if distance is None:
                warnings.warn(
                    "A distance with units must be provided to reach a target linear resolution"
                )
                raise ValueError

            target_beam_size = (target_resolution / distance).to(
                u.dimensionless_unscaled) * u.rad
        elif target_resolution.is_equivalent(u.rad):
            target_beam_size = target_resolution
        else:
            warnings.warn(
                "target_resolution must be either linear distance or angle")
            raise ValueError

        target_beam = Beam(major=target_beam_size,
                           minor=target_beam_size,
                           pa=0 * u.deg)
        if target_beam > cube.beam:
            cube = cube.convolve_to(target_beam)
        else:
            warnings.warn('Target linear resolution unreachable.')

    if target_rms is not None:
        if target_beam is None:
            target_beam = cube.beam
        noisevals = np.random.randn(*cube.shape)
        null_beam = Beam(major=1e-7 * u.deg, minor=1e-7 * u.deg, pa=0 * u.deg)
        noisevals[~np.isfinite(cube)] = np.nan
        noisecube = SpectralCube(noisevals,
                                 cube.wcs,
                                 header=cube.header,
                                 beam=null_beam,
                                 meta={'BUNIT': 'K'})
        noisecube = noisecube.with_mask(np.isfinite(cube))
        noisecube.allow_huge_operations = huge
        area_ratio = (orig_beam_area / target_beam.sr).to(
            u.dimensionless_unscaled).value
        noisecube = noisecube.convolve_to(target_beam)

        if (rmsname is not None) and (rmsmap is None):
            rmsmap = fits.getdata(os.path.join(datadir, rmsname)) * u.K
        if rmsmap is None:
            warnings.warn(
                "One of rmsmap or rmsname must be provided for noise homogenization"
            )
            raise FileNotFoundError

        rmsamplitude = rmsmap * area_ratio**0.5
        if np.all(rmsamplitude > target_rms):
            warnings.warn("All noise values larger than target value")
        else:
            addamplitude = (target_rms**2 - rmsamplitude**2)
            addamplitude[addamplitude < 0] = 0.0
            addamplitude.shape = addamplitude.shape
            noisevals = noisecube.filled_data[:]
            noisevals /= np.nanstd(noisevals)
            noisevals *= (addamplitude**0.5)
            cube.allow_huge_operations = huge
            cube += noisevals
    if type(outname) is str:
        cube.write(outdir + outname, overwrite=overwrite)
    if return_cube:
        return (cube)
    else:
        return (True)
Exemple #21
0
class Data3D(Data):
    """ Creates a data cube structure.

    Attributes:
        address: file name.
        data: the data cube.
    """
    def __init__(self, address):
        """Defines a new data cube object.

        Parameters:
            address (str): file name.
        """
        super(Data3D, self).__init__(address)
        self.logger = get_logger(__name__)

    def load(self):
        """Load the data cube"""
        try:
            self.data = SpectralCube.read(self.address)
        except:
            self.logger.warn('Trying to fix the cube')
            cube = fits.open(self.address)[0]
            cube.header['CUNIT3'] = 'm/s'
            cube.header['CRVAL3'] = cube.header['CRVAL3'] * 1.E3
            cube.header['CDELT3'] = cube.header['CDELT3'] * 1.E3
            self.data = SpectralCube(cube.data, WCS(cube.header))
            self.logger.info('Cube fixed')

    def save(self, filename=None, overwrite=True):
        """Save the data cube"""
        self.data.write(filename or self.address, overwrite=overwrite)

    @property
    def wcs(self):
        """Return the WCS with the position data."""
        return self.data.wcs.sub(['longitude', 'latitude'])

    def get_coord(self, xpix, ypix, frame='fk5'):
        """Return the (ra, dec) coordinates of the input pixel location.

        Parameters:
            xpix (float): x-position of the coordinate.
            ypix (float): y-position of the coordinate.
            frame (str, default=fk5): sky frame projection.

        Returns:
            coord (astropy.SkyCoord): sky coordinate of the input location.

        Note:
            xpix and ypix are zero based.
        """
        ra, dec = self.wcs.all_pix2world([[xpix, ypix]], 0)[0]
        return SkyCoord(ra=ra * u.degree, dec=dec * u.degree, frame=frame)

    def get_pixel(self, coord):
        crd = [[coord.ra.degree, coord.dec.degree]]
        return self.wcs.all_world2pix(crd, 0)[0]
        #return self.wcs.world_to_pixel(coord)

    def get_spectrum(self, coord=None, pixel=None):
        if coord is not None:
            xy = self.get_pixel(coord)
        elif pixel is not None:
            xy = pixel
        else:
            raise ValueError('Could not determine position')
        x, y = map(int, xy)
        self.logger.info('Extracting spectrum at pixel: %i, %i', x, y)
        return self.data[:, y, x]

    def get_avg_spectrum(self, coord, r=None):
        # Position
        xy = self.get_pixel(coord)
        x, y = map(int, xy)
        self.logger.info('Region centered at pixel: %i, %i', x, y)

        # Multiple beams
        bmaj = 0.
        bmin = 0.
        for beam in self.data.beams:
            bmaj += beam.major.to(u.deg).value
            bmin += beam.minor.to(u.deg).value
        bmaj = bmaj / len(self.data.beams)
        bmin = bmin / len(self.data.beams)

        # Get mask
        mask = image_circular_mask(self.data,
                                   xy=[x, y],
                                   r=r,
                                   bmin=bmin,
                                   bmaj=bmaj)

        # Get spectrum
        maskedcube = self.data.with_mask(mask)
        return maskedcube.mean(axis=(-2, -1))

    def rotate(self, angle, source, centre=(0, 0), mode='bilinear', **kwargs):
        """Rotate the cube.

        Parameters
            angle: angle of rotation in degrees.
            centre: centre of rotation.
            mode: interpolation mode.
        """
        #old_centre = self.centre

        # Rotate the cube
        aux = None
        for j, slc in enumerate(self.data.unmasked_data[:]):
            rotated = rotate(slc, angle, centre=centre, mode=mode)
            if aux is None:
                aux = np.array([rotated])
            else:
                aux = np.append(aux, [rotated], axis=0)

        # Create a new fits file
        hdu = fits.PrimaryHDU(aux)
        hdu.header = self.data.header
        hdu.header['COMMENT'] = 'Rotated %.3f deg, center %i, %i' % \
                ((angle,)+centre)
        self.logger.info('Image rotated %.1f deg, center %i, %i', angle,
                         *centre)

        # Redefine the reference pixel
        hdu.header['CRPIX1'] = aux.shape[2] / 2. + .5
        hdu.header['CRPIX2'] = aux.shape[1] / 2. + .5
        hdu.header['CRVAL1'] = source.position.ra.to(u.deg).value
        hdu.header['CRVAL2'] = source.position.dec.to(u.deg).value

        # Redifine header rotation
        #if 'CROTA2' in hdu.header:
        #    #if hdu.header['CROTA2']==angle:
        #    self.logger.info('Deleting rotation keywords from header')
        try:
            del hdu.header['CROTA2']
            del hdu.header['CROTA1']
        except KeyError:
            pass
            #else:
            #    self.logger.info('Changing rotation keywords from header')
            #    hdu.header['CROTA2'] = hdu.header['CROTA2']-angle
        #else:
        #    self.logger.info('Setting rotation header keywords')
        #    hdu.header['CROTA1'] = 0
        #    hdu.header['CROTA2'] = angle

        return hdu
add_noise = sys.argv[3]
if add_noise == "True" or add_noise == "T":
    add_noise = True
else:
    add_noise = False


data1, hdr1 = fits.getdata(fits1, header=True)
data2, hdr2 = fits.getdata(fits2, header=True)

if add_noise:
    data1 += np.random.normal(0.0, 0.788 / 10, data1.shape)
    data2 += np.random.normal(0.0, 0.788 / 10, data2.shape)

cube1 = SpectralCube(data=data1, wcs=WCS(hdr1))
cube1 = cube1.with_mask(LazyMask(np.isfinite, cube1))
cube2 = SpectralCube(data=data2, wcs=WCS(hdr2))
cube2 = cube2.with_mask(LazyMask(np.isfinite, cube2))

set1 = Mask_and_Moments(cube1)
mask = cube1 > 3*set1.scale
set1.make_mask(mask=mask)
set1.make_moments()
set1.make_moment_errors()
dataset1 = set1.to_dict()

set2 = Mask_and_Moments(cube2)
mask = cube2 > 3*set2.scale
set2.make_mask(mask=mask)
set2.make_moments()
set2.make_moment_errors()
Exemple #23
0
for thisfile in fl:
    fig, [[ax1, ax2], [ax3, ax4]] = plt.subplots(2, 2, constrained_layout=True)
    fig.set_size_inches(6.5, 6.5)
    cube = SpectralCube.read(thisfile)
    gal = os.path.split(thisfile)[-1].split('_')[0]
    shortfile = os.path.split(thisfile)[-1]

    try:
        mask = SpectralCube.read(degas_data +
                                 '/masks/{0}_mask.fits'.format(gal))
        mask = mask.with_spectral_unit(u.km / u.s, velocity_convention='radio')
        hdr = mask.header
        hdr['CTYPE3'] = 'VRAD'
        mask = SpectralCube(mask.filled_data[:], wcs.WCS(hdr), header=hdr)
        mask = mask.with_mask(mask.filled_data[:] > 0)
        mask = mask.spectral_interpolate(cube.spectral_axis)
        mask = mask.reproject(cube.header)

    except FileNotFoundError:
        print('No mask for ' + thisfile)
        mask = SpectralCube(np.ones(cube.shape),
                            wcs=cube.wcs,
                            header=cube.header)

    rmsamplitude = scm.noise_cube(cube.filled_data[:].value,
                                  box=5,
                                  spec_box=5,
                                  iterations=5,
                                  bandpass_smooth_window=21)
    s2n = cube.filled_data[:].value / rmsamplitude
np.save(
    hi_stackpath("radial_stacking_pixelsinbin_{0}_noCO.npy").format(wstring),
    num_pixels)
np.save(
    hi_stackpath("radial_stacking_pixelsinbin_north_{0}_noCO.npy").format(
        wstring), num_pixels_n)
np.save(
    hi_stackpath("radial_stacking_pixelsinbin_south_{0}_noCO.npy").format(
        wstring), num_pixels_s)

spec_shape = hi_cube_peakvel.shape[0]

peakvel_stack = SpectralCube(data=total_spectrum_hi_radial_peakvel.T.reshape(
    (spec_shape, bin_centers.size, 1)),
                             wcs=hi_cube_peakvel.wcs)
peakvel_stack = peakvel_stack.with_mask(
    np.ones_like(peakvel_stack, dtype='bool'))
peakvel_stack.write(hi_stackpath(
    "peakvel_stacked_radial_{0}_noCO.fits".format(wstring)),
                    overwrite=True)

peakvel_stack_n = SpectralCube(
    data=total_spectrum_hi_radial_peakvel_n.T.reshape(
        (spec_shape, bin_centers.size, 1)),
    wcs=hi_cube_peakvel.wcs)
peakvel_stack_n = peakvel_stack_n.with_mask(
    np.ones_like(peakvel_stack_n, dtype='bool'))
peakvel_stack_n.write(hi_stackpath(
    "peakvel_stacked_radial_north_{0}_noCO.fits".format(wstring)),
                      overwrite=True)
peakvel_stack_s = SpectralCube(
    data=total_spectrum_hi_radial_peakvel_s.T.reshape(
Exemple #25
0
def calc_structure_fcn(catalog, bootiter=0, doPlot=False):

    cat = catalog
    if 'sf_offset' not in cat.keys():
        keylist = [
            'sf_offset', 'sf_index', 'sf_ngood', 'sf_index_err',
            'sf_offset_err', 'vca_index', 'vca_index_err'
        ]
        for thiskey in keylist:
            c = Column(np.zeros(len(cat)) + np.nan, name=thiskey)
            cat.add_column(c)

    current_open_file = ''
    for cloud in cat:
        root = cloud['orig_file'].split('_')
        orig_file = 'COHRS_{0}_{1}.fits'.format(root[-2], root[-1])
        asgn_file = cloud['orig_file'] + '_fasgn.fits'
        if os.path.isfile(datadir + 'COHRS_tiles/' + orig_file):
            if current_open_file != datadir + 'COHRS_tiles/' + orig_file:
                hdu = fits.open(datadir + 'COHRS_tiles/' + orig_file,
                                memmap=False)
                cat.write('cohrs_structurefunc.fits', overwrite=True)
                w = wcs.WCS(hdu[0].header)
                hdr2 = w.to_header()
                hdr2['BMAJ'] = 15. / 3600
                hdr2['BMIN'] = 15. / 3600
                hdr2['BPA'] = 0.
                co = SpectralCube(hdu[0].data, w, header=hdr2)
                hdu = fits.open(datadir + 'ASGN/' + asgn_file, memmap=False)
                w = wcs.WCS(hdu[0].header)
                hdr2 = w.to_header()
                hdr2['BMAJ'] = 15. / 3600
                hdr2['BMIN'] = 15. / 3600
                hdr2['BPA'] = 0.
                asgn = SpectralCube(hdu[0].data, w, header=hdr2)

                #                masked_co = co.with_mask(asgn>0*u.dimensionless_unscaled)
                #                moment = masked_co.moment(0)

                current_open_file = datadir + 'COHRS_tiles/' + orig_file

            print(cloud['cloud_id'])
            mask = (asgn == cloud['cloud_id'] * u.dimensionless_unscaled)
            subcube = co.with_mask(mask)
            subcube = subcube.subcube_from_mask(mask)
            #            subcube.moment0().quicklook()
            #            plt.show()
            if subcube.shape[0] > 10:
                # zeros = np.zeros_like(subcube) # np.random.randn(*subcube.shape)*0.5
                # concatdata = np.vstack([subcube.filled_data[:],zeros])
                # hdr2 = subcube.wcs.to_header()
                # hdr2['BMAJ'] = 15./3600
                # hdr2['BMIN'] = 15./3600
                # hdr2['BPA'] = 0.
                # newcube = SpectralCube(concatdata,subcube.wcs,header=hdr2)
                # if True:
                try:
                    pcaobj = pca.PCA(subcube,
                                     distance=cloud['bgps_distance_pc'] * u.pc)
                    vcaobj = vca.VCA(subcube,
                                     distance=cloud['bgps_distance_pc'] * u.pc)
                    vcaobj.run(verbose=False, high_cut=0.3 / u.pix)
                    pcaobj.run(verbose=True,
                               mean_sub=True,
                               min_eigval=0.9,
                               eigen_cut_method='proportion')
                    cloud['sf_index'] = pcaobj.index
                    cloud['sf_offset'] = pcaobj.intercept.value
                    cloud['sf_ngood'] = np.min([
                        np.isfinite(pcaobj.spatial_width).sum(),
                        np.isfinite(pcaobj.spectral_width).sum()
                    ])

                    cloud['sf_index_err'] = (pcaobj.index_error_range[1] -
                                             pcaobj.index_error_range[0]) * 0.5
                    cloud['sf_offset_err'] = (
                        (pcaobj.intercept_error_range[1] -
                         pcaobj.intercept_error_range[0]) * 0.5).value
                    cloud['vca_index'] = vcaobj.slope
                    cloud['vca_index_err'] = vcaobj.slope_err
                    print(
                        '{0} +/- {1}'.format(cloud['sf_index'],
                                             cloud['sf_index_err']),
                        cloud['sf_offset'])
                    # import pdb; pdb.set_trace()
                # else:
                except:
                    pass

    cat.write('output_catalog2.fits', overwrite=True)
def reduce_and_save(filename,
                    add_noise=False,
                    regrid_linewidth=False,
                    rms_noise=0.001 * u.K,
                    output_path="",
                    cube_output=None,
                    nsig=3,
                    slicewise_noise=True):
    '''
    Load the cube in and derive the property arrays.
    '''

    if add_noise or regrid_linewidth:

        sc = SpectralCube.read(filename)

        if add_noise:
            if rms_noise is None:
                raise TypeError("Must specify value of rms noise.")

            cube = sc.filled_data[:].value

            # Optionally scale noise by 1/10th of the 98th percentile in the
            # cube
            if rms_noise == 'scaled':
                rms_noise = 0.1 * \
                    np.percentile(cube[np.isfinite(cube)], 98) * sc.unit

            from scipy.stats import norm
            if not slicewise_noise:
                cube += norm.rvs(0.0, rms_noise.value, cube.shape)
            else:
                spec_shape = cube.shape[0]
                slice_shape = cube.shape[1:]
                for i in range(spec_shape):
                    cube[i, :, :] += norm.rvs(0.0, rms_noise.value,
                                              slice_shape)

            sc = SpectralCube(data=cube * sc.unit,
                              wcs=sc.wcs,
                              meta={"BUNIT": "K"})

            mask = LazyMask(np.isfinite, sc)
            sc = sc.with_mask(mask)

        if regrid_linewidth:
            # Normalize the cubes to have the same linewidth
            # channels_per_sigma=20 scales to the largest mean line width in
            # SimSuite8 (~800 km/s; Design 22). So effectively everything is
            # "smoothed" to have this line width
            # Intensities are normalized by their 95% value.
            sc = preprocessor(sc,
                              min_intensity=nsig * rms_noise,
                              norm_intensity=True,
                              norm_percentile=95,
                              channels_per_sigma=20)

    else:
        sc = filename

    # Run the same signal masking procedure that was used for the
    # COMPLETE cubes
    if add_noise:
        # The default settings were set based on these cubes
        sc = make_signal_mask(sc)[0]

    reduc = Mask_and_Moments(sc, scale=rms_noise)
    if not add_noise:
        reduc.make_mask(mask=reduc.cube > nsig * reduc.scale)

    reduc.make_moments()
    reduc.make_moment_errors()

    # Remove .fits from filename
    save_name = os.path.splitext(os.path.basename(filename))[0]

    reduc.to_fits(os.path.join(output_path, save_name))

    # Save the noisy cube too
    if add_noise or regrid_linewidth:
        save_name += ".fits"
        if cube_output is None:
            sc.hdu.writeto(os.path.join(output_path, save_name))
        else:
            sc.hdu.writeto(os.path.join(cube_output, save_name))
Exemple #27
0
def calc_noise_in_cube(cube, masking_scheme='simple', mask=None,
                       spatial_average_npix=None,
                       spatial_average_nbeam=5.0,
                       spectral_average_nchan=5, verbose=False):
    """
    Estimate rms noise in a (continuum-subtracted) spectral cube.

    Parameters
    ----------
    cube : SpectralCube object
        Input spectral cube (needs to be continuum-subtracted)
    masking_scheme : {'simple', 'user'}, optional
        Scheme for flagging signal in the cube. 'simple' means to flag
        all values above 3*rms or below -3*rms (default scheme);
        'user' means to use the user-specified mask (i.e., `mask`).
    mask : `np.ndarray` object, optional
        User-specified signal mask (this parameter is ignored if
        `masking_scheme` is not 'user')
    spatial_average_npix : int, optional
        Size of the spatial averaging box, in terms of pixel number
        If not None, `spatial_average_nbeam` will be ingored.
        (Default: None)
    spatial_average_nbeam : float, optional
        Size of the spatial averaging box, in the unit of beam FWHM
        (Default: 5.0)
    spectral_average_nchan : int, optional
        Size of the spectral averaging box, in terms of channel number
        (Default: 5)
    verbose : bool, optional
        Whether to print the detailed processing information in terminal
        Default is to not print.
    
    Returns
    -------
    rmscube : SpectralCube object
        Spectral cube containing the rms noise at each ppv location
    """

    from scipy.ndimage import generic_filter
    from astropy.stats import mad_std

    if masking_scheme not in ['simple', 'user']:
        raise ValueError("'masking_scheme' should be specified as"
                         "either 'simple' or 'user'")
    elif masking_scheme == 'user' and mask is None:
        raise ValueError("'masking_scheme' set to 'user', yet "
                         "no user-specified mask found")

    # extract negative values (only needed if masking_scheme='simple')
    if masking_scheme == 'simple':
        if verbose:
            print("Extracting negative values...")
        negmask = cube < (0 * cube.unit)
        negdata = cube.with_mask(negmask).filled_data[:].value
        negdata = np.stack([negdata, -1 * negdata], axis=-1)
    else:
        negdata = None

    # find rms noise as a function of channel
    if verbose:
        print("Estimating rms noise as a function of channel...")
    if masking_scheme == 'user':
        mask_v = mask
    elif masking_scheme == 'simple':
        rms_v = mad_std(negdata, axis=(1, 2, 3), ignore_nan=True)
        uplim_v = (3 * rms_v * cube.unit).reshape(-1, 1, 1)
        lolim_v = (-3 * rms_v * cube.unit).reshape(-1, 1, 1)
        mask_v = (((cube - uplim_v) < (0 * cube.unit)) &
                  ((cube - lolim_v) > (0 * cube.unit)))
    rms_v = cube.with_mask(mask_v).mad_std(axis=(1, 2)).quantity.value
    rms_v = generic_filter(rms_v, np.nanmedian,
                           mode='constant', cval=np.nan,
                           size=spectral_average_nchan)
    
    # find rms noise as a function of sightline
    if verbose:
        print("Estimating rms noise as a function of sightline...")
    if masking_scheme == 'user':
        mask_s = mask
    elif masking_scheme == 'simple':
        rms_s = mad_std(negdata, axis=(0, 3), ignore_nan=True)
        uplim_s = 3 * rms_s * cube.unit
        lolim_s = -3 * rms_s * cube.unit
        mask_s = (((cube - uplim_s) < (0 * cube.unit)) &
                  ((cube - lolim_s) > (0 * cube.unit)))
    rms_s = cube.with_mask(mask_s).mad_std(axis=0).quantity.value
    if spatial_average_npix is None:
        beamFWHM_pix = (cube.beam.major.to(u.deg).value /
                        np.abs(cube.wcs.celestial.wcs.cdelt.min()))
        beamFWHM_pix = np.max([beamFWHM_pix, 3.])
        spatial_average_npix = int(spatial_average_nbeam *
                                   beamFWHM_pix)
    rms_s = generic_filter(rms_s, np.nanmedian,
                           mode='constant', cval=np.nan,
                           size=spatial_average_npix)

    # create rms noise cube from the tensor product of rms_v and rms_s
    if verbose:
        print("Creating rms noise cube (direct tensor product)...")
    rmscube = SpectralCube(np.einsum('i,jk', rms_v, rms_s),
                           wcs=cube.wcs,
                           header=cube.header.copy(strip=True))
    rmscube.allow_huge_operations = cube.allow_huge_operations
    # correct the normalization of the rms cube
    if masking_scheme == 'user':
        mask_n = mask
    elif masking_scheme == 'simple':
        rms_n = mad_std(negdata, ignore_nan=True)
        uplim_n = 3 * rms_n * cube.unit
        lolim_n = -3 * rms_n * cube.unit
        mask_n = (((cube - uplim_n) < (0 * cube.unit)) &
                  ((cube - lolim_n) > (0 * cube.unit)))
    rms_n = cube.with_mask(mask_n).mad_std().value
    rmscube /= rms_n

    # apply NaN mask
    rmscube = rmscube.with_mask(cube.mask.include())

    # check unit
    if rmscube.unit != cube.unit:
        rmscube = rmscube * (cube.unit / rmscube.unit)

    return rmscube
Exemple #28
0
    fig.set_size_inches(6.5, 6.5)
    for gal, ax in zip(subtable['NAME'], axlist.flatten()):
        eta_mb = eta_mb_dict[molecule]
        degas_cube_name = 'IR5/{0}_{1}_rebase3_smooth1.3_hanning1.fits'.format(gal, molecule)
        if not os.path.exists(degas_data + degas_cube_name):
            ax.set_title(gal)
            ax.text(0.5, 0.5, 'No data',ha='center')
            continue
        cube_degas = SpectralCube.read(degas_data + degas_cube_name)
        cube_degas = cube_degas / eta_mb
        mask = SpectralCube.read(degas_data + '/masks/{0}_mask.fits'.format(gal))
        mask = mask.with_spectral_unit(u.km/u.s, velocity_convention='radio')
        hdr = mask.header
        hdr['CTYPE3'] = 'VRAD'
        mask = SpectralCube(mask.filled_data[:], wcs.WCS(hdr), header=hdr)
        mask = mask.with_mask(mask.filled_data[:] > 0)
        mask = mask.spectral_interpolate(cube_degas.spectral_axis)
        mask = mask.reproject(cube_degas.header)

        fl = glob.glob(empire_data + 'EMPIRE_{0}_{1}_*.fits'.format(gal.lower(),molecule.lower()))
        hdulist = fits.open(fl[0])
        hdu = sanitize(hdulist[0])
        cube_empire = SpectralCube(data=hdu.data, header=hdu.header, wcs=wcs.WCS(hdu.header))
        empire_mask = np.isfinite(hdu.data)
        cube_empire = cube_empire.with_mask(empire_mask)

        channel_ratio = ((cube_degas.spectral_axis[1]
                          - cube_degas.spectral_axis[0]) / 
                         (cube_empire.spectral_axis[1]
                          - cube_empire.spectral_axis[0])).to(u.dimensionless_unscaled).value