Beispiel #1
0
def import_fits(filename):
	"""Imports a FITS radio image from CASA pipeline"""
	
	fits_image_filename = os.getcwd()+filename
	with fits.open(fits_image_filename) as hdul:
		#print(hdul.info())
		data=hdul[0].data

	#now convert to Jy/str surface brigthness
	
	header = fits.getheader(fits_image_filename)
	if header['BUNIT'] == 'Jy/beam':
		beam = Beam.from_fits_header(header)
		SB=((data*u.Jy/u.beam).to(u.MJy/u.sr, equivalencies=u.beam_angular_area(beam)))[0,0,:,:].value
	elif header['BUNIT'] == 'JY/BEAM':
		beam = Beam.from_fits_header(header)
		SB=((data*u.Jy/u.beam).to(u.MJy/u.sr, equivalencies=u.beam_angular_area(beam)))[0,0,:,:].value
	elif header['BUNIT'] == 'MJy/sr':
		SB=data
	
	"""SB is a 2-d array with Surface_brigthness values in MJy/sr. For masked arrays, some values are nan, need to create a mask to 
	these values. Before that, need to set all values not within data range to NAN. Using SB.data can access the original array."""
	
	
	
	sb_maskedNAN = np.ma.array(SB, mask=np.isnan(SB))	
	
	
	array = np.ma.array(sb_maskedNAN, mask=np.isnan(sb_maskedNAN))	
	
	print('Max value in image is :', np.max(sb_maskedNAN), ' MJy/sr')
	print('Min value in image is :', np.min(sb_maskedNAN), ' MJy/sr')
def jy_beam_MJy_sr(data, header):
    """Funtion which converts fits data into units of Jy/sr"""

    if header['BUNIT'] == 'Jy/beam':
        beam = Beam.from_fits_header(header)
        SB = ((data * u.Jy / u.beam).to(
            u.MJy / u.sr, equivalencies=u.beam_angular_area(beam))).value
    elif header['BUNIT'] == 'JY/BEAM':
        beam = Beam.from_fits_header(header)
        SB = ((data * u.Jy / u.beam).to(
            u.MJy / u.sr, equivalencies=u.beam_angular_area(beam))).value
    elif header['BUNIT'] == 'MJy/sr':
        SB = data

    return SB
Beispiel #3
0
def column_density(flux, beam, wave, t, kappa, mu=2.8):
    """
    Computes column density from continuum data

    Parameters
    ----------
    flux : float
        flux in Jy/beam
    beam : array like
        beam size in arcseconds
    wave : float
        wavelength (m)
    t: float (optional)
        temperature (K)
    kappa: float
        dust opacity per unit mass (cm^2g^-1)
    mu : float (optional)
        molecular weight (default = 2.8; i.e. assumes density is given as density
        of hydrogen molecules)
    """
    beam = beam * u.arcsec
    omega_beam = beam_solid_angle(beam)
    flux = (flux * u.Jy / u.beam).to(
        u.Jy / u.sr, equivalencies=u.beam_angular_area(omega_beam))
    wave = wave * u.m
    t = t * u.K
    kappa = kappa * (u.cm**2 / u.g)

    B = blackbody_nu(wave.to(u.Hz, equivalencies=u.spectral()), t)

    N = flux / (mu * ap.M_p * kappa * B)
    N = N.to(1. / u.cm**2)

    return N
def contour_plot(ax, contour_file, contour_type, image_beam):
    """Plots contours over the main image, can be either from the same image or from a different one, fits file."""

    cblock = import_contours(contour_file)
    cdata = cblock[0]
    cheader = cblock[1]
    cwcs = WCS(cheader)

    contour_type = str(contour_type)
    ax.set_autoscale_on(False)

    norm = ImageNormalize(cdata,
                          interval=MinMaxInterval(),
                          stretch=SqrtStretch())

    if contour_type == "automatic":
        spacing = contour_bias
        n = 6  #number of contours
        ub = np.max(cdata)
        lb = np.min(cdata)

        def level_func(lb, ub, n, spacing=1.1):
            span = (ub - lb)
            dx = 1.0 / (n - 1)
            return [lb + (i * dx)**spacing * span for i in range(n)]

        levels = level_func(lb, ub, n, spacing=float(spacing))
        levels = np.array(levels)[np.array(levels) > 0.]
        print('Generated Levels for contour are: ', levels, 'MJy/sr')
        CS = ax.contour(cdata,
                        levels=levels,
                        colors='black',
                        transform=ax.get_transform(cwcs.celestial),
                        alpha=1.0,
                        linewidths=1)
    if contour_type == "sigma":
        contour_levels = list(map(float, args.contour_levels))
        sigma_levels = np.array(contour_levels)
        rms = (0.0004 * u.Jy / u.beam).to(
            u.MJy / u.sr, equivalencies=u.beam_angular_area(image_beam))
        levels = rms * sigma_levels
        print('Sigma Levels for contour are: ', sigma_levels, 'sigma')
        CS = ax.contour(cdata,
                        levels=levels,
                        norm=norm,
                        transform=ax.get_transform(cwcs.celestial),
                        colors='white',
                        alpha=0.5)
        #plt.title(label='Contours at %s sigma' % contour_levels)
    if contour_type == "manual":
        levels = list(map(float, args.contour_levels))
        print('Contour Levels are: ', levels, 'MJy/sr')
        CS = ax.contour(cdata,
                        levels=levels,
                        norm=norm,
                        transform=ax.get_transform(cwcs.celestial),
                        colors='white',
                        alpha=0.5,
                        linewidths=1.0)
Beispiel #5
0
def mass_jyperbeam(flux, beam, pixel_size, wave, t, kappa, distance):
    """
    Takes flux in Jy/beam summed over some area and computes the mass using
    beam and pixel information

    Parameters:
    flux : float
        flux in Jy/beam
    beam : array like
        beam size in arcseconds
    pixel_size : number
        pixel size in arcseconds
    wave : float
        wavelength (m)
    t: float (optional)
        temperature (K)
    kappa: float
        dust opacity per unit mass (cm^2g^-1)
    distance: float
        distance to the object (pc)

    """
    beam = beam * u.arcsec
    pixel_size = pixel_size * u.arcsec
    omega_beam = beam_solid_angle(beam)
    flux = (flux * u.Jy / u.beam).to(
        u.Jy / u.sr, equivalencies=u.beam_angular_area(omega_beam))
    integrated_flux = flux * pixel_size**2
    integrated_flux = integrated_flux.to(u.Jy)

    wave = wave * u.m
    t = t * u.K
    kappa = kappa * (u.cm**2 / u.g)
    distance = distance * (u.pc)

    B = blackbody_nu(wave.to(u.Hz, equivalencies=u.spectral()), t)
    B = B * u.sr

    m = (distance**2. * integrated_flux) / (kappa * B)
    m = m.to(ap.solMass)

    return m
Beispiel #6
0
def test_beamarea_equiv():

    major = 0.1 * u.rad
    beam = Beam(major, major, 30 * u.deg)

    conv_factor = u.beam_angular_area(beam.sr)

    assert_quantity_allclose(
        (1 * u.Jy / u.beam).to(u.Jy / u.sr, equivalencies=conv_factor),
        (1 * u.Jy / u.beam).to(u.Jy / u.sr, equivalencies=beam.beamarea_equiv))

    assert_quantity_allclose(
        (1 * u.Jy / u.sr).to(u.Jy / u.beam, equivalencies=conv_factor),
        (1 * u.Jy / u.sr).to(u.Jy / u.beam, equivalencies=beam.beamarea_equiv))

    # Add a by-hand check
    value = (1 * u.Jy / u.sr).to(u.Jy / u.beam,
                                 equivalencies=conv_factor).value
    byhand_value = 1 * beam.sr.value
    npt.assert_allclose(value, byhand_value)

arrays = []
i = 0

freq_ar = np.array([4.5, 5.5, 6.5, 7.5, 8.5, 9.5, 10.5])

for im in images:
    with fits.open(im) as hdul:
        data = hdul[0].data[0, 0, :, :]
    header = fits.getheader(im)
    wcs = WCS(header)
    print(wcs)
    beam = Beam.from_fits_header(header)
    SB = ((data * u.Jy / u.beam).to(
        u.MJy / u.sr, equivalencies=u.beam_angular_area(beam))).value
    where_are_NaNs = np.isnan(SB)
    SB[where_are_NaNs] = 0.0
    #SB_masked = np.ma.masked_invalid(SB)
    where_are_neg = np.where(SB < 0)
    SB[where_are_neg] = 0.0
    result = ndimage.zoom(SB, 1 / 4.0)
    print(np.shape(result))
    i += 1
    arrays.append(result)

spectral_ar = np.ones_like(arrays[0]) * 10

for freq in freq_ar:
    for i in range(np.shape(spectral_ar)[0] - 1):
        for j in range(np.shape(spectral_ar)[1] - 1):
Beispiel #8
0
def regrid_3d_sb(
    *,
    sim_data,
    sb,
    pixel_size=1.8 * _u.arcsec,
    beam_fwhm=5 * _u.arcsec,
    z=0.05,
):
    """
    Grids & smooths the surface brightness, for a given redshift,
    pixel size, and observing beam information (currently assumes observing
    beam is a circular 2D Gaussian with constant & FWHM)

    Parameters
    ---------
    sim_data : HDF5 File
        The simulation data file
    sb : u.mJy / u.beam
        Surface brightness, in units of mJy per beam
    pixel_size : u.arcsec
        The gridded pixel size, in arcseconds
    beam_fwhm : u.arcsec
        The 2D observing beam Gaussian fwhm, in arcseconds
    z : float
        The redshift this sourced is observed at

    Returns
    -------
    grid_x : u.arcsec
        X grid in arcseconds
    grid_y : u.arsec
        Y grid in arcseconds
    sb : u.mJy / u.beam
        Gridded and smoothed surface brightness, in units of mJy per beam
    """
    fwhm_to_sigma = 1 / (8 * _np.log(2))**0.5
    beam_sigma = beam_fwhm * fwhm_to_sigma
    omega_beam = 2 * _np.pi * beam_sigma**2  # Area for a circular 2D gaussian

    z = 0.05
    kpc_per_arcsec = _cosmo.kpc_proper_per_arcmin(z)

    # Create our grid
    grid_res = pixel_size.to(_u.arcsec)
    x_min = (sim_data.mx[0] * sim_data.unit_length / kpc_per_arcsec).to(
        _u.arcsec)
    x_max = (sim_data.mx[-1] * sim_data.unit_length / kpc_per_arcsec).to(
        _u.arcsec)
    y_min = (sim_data.mz[0] * sim_data.unit_length / kpc_per_arcsec).to(
        _u.arcsec)
    y_max = (sim_data.mz[-1] * sim_data.unit_length / kpc_per_arcsec).to(
        _u.arcsec)

    new_x = _np.arange(x_min.value, x_max.value,
                       grid_res.value)  # in arcsec now
    new_y = _np.arange(y_min.value, y_max.value,
                       grid_res.value)  # in arcsec now
    grid_x, grid_y = _np.meshgrid(new_x, new_y, indexing="xy")  # in arcsec

    old_x = ((sim_data.mx * sim_data.unit_length / kpc_per_arcsec).to(
        _u.arcsec).value)  # in arcsec
    old_z = ((sim_data.mz * sim_data.unit_length / kpc_per_arcsec).to(
        _u.arcsec).value)  # in arcsec

    # Regrid data
    # everything is in arcsec
    # save our units first, to add them back after
    sb_units = sb.unit
    sb_gridded = (_scipy.interpolate.interpn(
        points=(old_z, old_x),
        values=sb.value,
        xi=(grid_y, grid_x),
        method="linear",
        bounds_error=False,
        fill_value=0,
    ) * sb_units)

    # Smooth data
    stddev = beam_sigma / pixel_size
    kernel = _Gaussian2DKernel(x_stddev=stddev.value)
    sb_units = sb_gridded.unit
    sb_smoothed = _convolve(sb_gridded.value, kernel) * sb_units

    # Convert from per sr to per beam
    sb_final = sb_smoothed.to(_u.mJy / _u.beam,
                              equivalencies=_u.beam_angular_area(omega_beam))

    return (grid_x * _u.arcsec, grid_y * _u.arcsec, sb_final)
Beispiel #9
0
matplotlib.rcParams['figure.dpi'] = 120
matplotlib.rcParams['font.sans-serif'] = "Nimbus Roman"

#coordinates of BD+60 2522
star_coord = SkyCoord("23h20m44.5s +61d11m40.5s", frame='icrs')

#fits_image_filename = 'fits/ngc7635_g0.5_briggs1.0_nsig5.image.5sig_masked.fits'
fits_image_filename = 'fits/ngc7635_g0.5_briggs1.0_nsig5.image.tt0.fits'

with fits.open(fits_image_filename) as hdul:
    data = hdul[0].data[0, 0, :, :]
header = fits.getheader(fits_image_filename)

beam = Beam.from_fits_header(header)
SB = ((data * u.Jy / u.beam).to(u.MJy / u.sr,
                                equivalencies=u.beam_angular_area(beam))).value
SB_masked = np.ma.masked_invalid(SB)


def optical_depth(flux):

    SB_erg = flux * 1e-17
    T = 8000  #K
    nu = 8e9  # central frequency of our broadband observations
    c = 3e10  #speed of light in cgs
    k_b = 1.38e-16  #boltzmann constant in cgs
    tau = -np.log(1 - (c**2 * SB_erg) / (2 * k_b * T * (nu**2)))
    return tau


# Position of NGC 7635: 23 20 48.3 +61 12 06
Beispiel #10
0
 def beamarea_equiv(self):
     return u.beam_angular_area(self.sr)