Exemplo n.º 1
1
hi_fig.hide_xaxis_label()
hi_fig.hide_yaxis_label()
hi_fig.hide_tick_labels()
hi_fig.set_title(r"HI")
hi_fig.set_nan_color("k")
hi_fig.show_regions("pvslices_finalfig.reg")

co21_fig = FITSFigure(co21_proj.hdu, subplot=(2, 3, 3), figure=fig)
co21_fig.show_grayscale()
co21_fig.hide_xaxis_label()
co21_fig.hide_yaxis_label()
co21_fig.hide_tick_labels()
co21_fig.set_title(r"CO(2-1)")

for path, pnum in zip(paths[4:7], [4, 5, 6]):
    pv = extract_pv_slice(hi_cube, path)
    pv_co21 = extract_pv_slice(co21_cube, path)

    pv_fig = FITSFigure(pv, subplot=(2, 3, pnum), figure=fig)
    pv_fig.show_grayscale()
    pv_fig.show_contour(pv_co21, levels=np.arange(3 * co21_sigma, 20 * co21_sigma, 4 * co21_sigma), colors="g")

    pv_fig.hide_xaxis_label()
    pv_fig.hide_xtick_labels()

    if pnum != 4:
        pv_fig.hide_yaxis_label()
        pv_fig.hide_ytick_labels()

p.tight_layout()
Exemplo n.º 2
0
def pv_wedge(cube, center, length, min_theta, max_theta,
             ntheta=90, width=1):
    '''
    Create a PV slice from a wedge.
    '''

    y0, x0 = center

    thetas = np.linspace(min_theta, max_theta, ntheta)

    pv_slices = []

    for i, theta in enumerate(thetas):

        start_pt = (y0 - (length / 2.) * np.sin(theta),
                    x0 - (length / 2.) * np.cos(theta))

        end_pt = (y0 + (length / 2.) * np.sin(theta),
                  x0 + (length / 2.) * np.cos(theta))

        path = Path([start_pt, end_pt], width=width)

        if i == 0:
            pv_slice = extract_pv_slice(cube, path)
            pv_path_slice, header = pv_slice.data, pv_slice.header
        else:
            pv_path_slice = extract_pv_slice(cube, path).data

        pv_slices.append(pv_path_slice)

        # Track the smallest shape
        if i == 0:
            path_length = pv_path_slice.shape[1]
        else:
            new_path_length = pv_path_slice.shape[1]
            if new_path_length < path_length:
                path_length = new_path_length

    header["NAXIS1"] = path_length

    # Now loop through and average together
    avg_pvslice = np.zeros((cube.shape[0], path_length), dtype='float')

    for pvslice in pv_slices:
        avg_pvslice += pvslice[:, :path_length]

    avg_pvslice /= float(ntheta)

    return PrimaryHDU(avg_pvslice, header=header)
Exemplo n.º 3
0
def pv_wedge(cube, center, length, min_theta, max_theta, ntheta=90, width=1):
    '''
    Create a PV slice from a wedge.
    '''

    y0, x0 = center

    thetas = np.linspace(min_theta, max_theta, ntheta)

    pv_slices = []

    for i, theta in enumerate(thetas):

        start_pt = (y0 - (length / 2.) * np.sin(theta),
                    x0 - (length / 2.) * np.cos(theta))

        end_pt = (y0 + (length / 2.) * np.sin(theta),
                  x0 + (length / 2.) * np.cos(theta))

        path = Path([start_pt, end_pt], width=width)

        if i == 0:
            pv_slice = extract_pv_slice(cube, path)
            pv_path_slice, header = pv_slice.data, pv_slice.header
        else:
            pv_path_slice = extract_pv_slice(cube, path).data

        pv_slices.append(pv_path_slice)

        # Track the smallest shape
        if i == 0:
            path_length = pv_path_slice.shape[1]
        else:
            new_path_length = pv_path_slice.shape[1]
            if new_path_length < path_length:
                path_length = new_path_length

    header["NAXIS1"] = path_length

    # Now loop through and average together
    avg_pvslice = np.zeros((cube.shape[0], path_length), dtype='float')

    for pvslice in pv_slices:
        avg_pvslice += pvslice[:, :path_length]

    avg_pvslice /= float(ntheta)

    return PrimaryHDU(avg_pvslice, header=header)
Exemplo n.º 4
0
 def pvdraw(self):
 ###--generate PV diagram---###
     if self.header["naxis"] == 3: da = self.data
     else                        : da = self.data[0]
     
     if self.vr == None:
         pv = extract_pv_slice(da, Path(self.slc()))
     else:
         vii = int(self.header["crpix3"]+
                  (self.vr[0] - self.header["crval3"]/1000.) \
                   /(self.header["cdelt3"]/1000.))-1
         vff = int(self.header["crpix3"]+
                  (self.vr[1] - self.header["crval3"]/1000.) \
                   /(self.header["cdelt3"]/1000.))-1
         pv = extract_pv_slice(da[vii:vff], Path(self.slc()))
     return pv.data
Exemplo n.º 5
0
	def drawLV(fitsName,saveFITS=None, RMS=0.5, cutLevel=3.):
 
		if saveFITS==None:
			saveFITS=fitsName[:-5] + "_LV.fits"
 
		CO12HDU= fits.open(fitsName)[0]
		data,head= CO12HDU.data,CO12HDU.header
 
		wcs=WCS(head)
		
		Nz,Ny,Nx=data.shape
		beginP=[0, (Ny-1.)/2.]
		
		endP= [(Nx) , (Ny-1.)/2.]

		widthPix=2 
		from pvextractor import extract_pv_slice,Path
		
		endpoints = [beginP,endP]
		xy = Path(endpoints,width= widthPix )
		
		pv = extract_pv_slice(  CO12HDU, xy)
		
		
		os.system("rm " +saveFITS )
		
		
		pv.writeto(saveFITS)

		if 1: #modify the first 
	
			pvData,pvHead=myFITS.readFITS( saveFITS )
			
			
			pvHead["CDELT1"]=head["CDELT1"]
			pvHead["CRPIX1"]=head["CRPIX1"]
			pvHead["NAXIS1"]=head["NAXIS1"]
			pvHead["CRVAL1"]=head["CRVAL1"]
			
 
		#data[data<cutLevel*RMS ]=0 #by default, we remove those emissions less than 3 sgima


		# resolution
		res=30./3600. 

		PVData2D=np.sum(data,axis=1,dtype=float)*res

		
		
		if PVData2D.shape==pvData.shape:
			#.....
			#os.system("rm " +saveFITS )

			fits.writeto(saveFITS,PVData2D,header=pvHead,overwrite=True)
		else:
 
			print ("The shape of pvdata with manual integration is unequal!" )
Exemplo n.º 6
0
	def creatPPVHeader(fitsName,saveFITS=None):
		"""
		produce the LV header for a fitsName, this function used in dendrogram
		:param fitsName:
		:param saveFITS:
		:return:
		"""


		if saveFITS==None:

			fitsName=os.path.split(fitsName)[1]

			saveFITS=fitsName[0:-5]+"LVHeader.fits"


		CO12HDU= fits.open(fitsName)[0]
		data,head= myFITS.readFITS(fitsName)

		#
		wcs=WCS(head)

		Nz,Ny,Nx=data.shape
		beginP=[0, (Ny-1.)/2.]

		endP= [(Nx) , (Ny-1.)/2.]
		#get pv diagrame
		widthPix=2
		from pvextractor import extract_pv_slice,Path

		endpoints = [beginP,endP]
		xy = Path(endpoints,width= widthPix )

		pv = extract_pv_slice(  CO12HDU, xy)


		os.system("rm " +saveFITS )


		pv.writeto(saveFITS)

		if 1: #modify the first

			pvData,pvHead=myFITS.readFITS( saveFITS )

			pvHead["CDELT1"]=head["CDELT1"]
			pvHead["CRPIX1"]=head["CRPIX1"]
			pvHead["NAXIS1"]=head["NAXIS1"]

			pvHead["CRVAL1"]=head["CRVAL1"]

			os.system("rm " +saveFITS )


			fits.writeto(saveFITS,pvData,header=pvHead,overwrite=True)
def get_pvs(cubefn, endpoints):
    fullcubefn = os.path.join(datapath_w51, cubefn)
    cube = spectral_cube.SpectralCube.read(fullcubefn)
    velo = cube.spectral_axis
    cdelt = pvextractor.utils.wcs_utils.get_spectral_scale(cube.wcs)
    #cube,velo,cdelt = pvextractor.utils.get_cube_info(cubefn)
    pvPath = pvextractor.geometry.path.Path(endpoints, width=60*u.arcsec)
    pv = pvextractor.extract_pv_slice(cube, pvPath)
                                      #respect_nan=False)
    npv = len(endpoints)
    return (pv,npv,velo,cdelt)
Exemplo n.º 8
0
def extract_pv_diagram(image, xy=(0., 0.), pa=0., length=100, width=1):

    ny, nx, nfreq, npol = image.image.shape

    # Create a data cube that is appropriately shaped.

    cube = numpy.empty((nfreq, ny, nx))
    for i in range(nfreq):
        cube[i, :, :] = image.image[:, :, i, 0]

    # Create the Path object.

    x0, y0 = xy

    line = [(x0-length/2*numpy.sin(pa),y0-length/2*numpy.cos(pa)), \
            (x0+length/2*numpy.sin(pa), y0+length/2*numpy.cos(pa))]

    path = pvextractor.Path(line, width=width)

    # Extract the PV diagram along the Path

    pv = pvextractor.extract_pv_slice(cube, path)

    # Convert back to my Image class.

    pvdiagram = numpy.empty((1, pv.data.shape[1], pv.data.shape[0], 1))
    for i in range(pv.data.shape[0]):
        pvdiagram[0, :, i, 0] = pv.data[i, :]

    # Get the velocity.

    velocity = c * (image.header["RESTFRQ"] - image.freq) / \
            image.header["RESTFRQ"]

    # Get the x coordinates.

    x0 = 0.
    dx = image.header["CDELT2"] * numpy.pi / 180 / arcsec
    nx0 = int(pv.data.shape[1] / 2) + 1

    x = (numpy.arange(pv.data.shape[1]) - (nx0 - 1)) * dx + x0

    return Image(pvdiagram, x=x, velocity=velocity, freq=image.freq)
Exemplo n.º 9
0
def PV_diagram_plot(filename, label, length=4 * u.arcsec, position_angle=0):

    cube = spectral_cube.SpectralCube.read(filename)

    # let's make the "parallel" PV diagram.

    # The path defines the line, whereupon normal
    # dimension is collapsed. I.e. the path line defines the offset direction
    # vector in the pv diagram.

    image_path = Path([*pv_path(cube.header, length, position_angle)], width=3)

    hdu = extract_pv_slice(cube.hdu.data, image_path)
    PV_file_name = 'pv_test_file.fits'
    save_extracted_pv_slice_hdu(hdu, cube.hdu.header, PV_file_name)
    image_data, im_hdr = load_fits_im(PV_file_name)

    fig = plt.figure()
    ax = fig.add_subplot(1, 1, 1)

    im = ax.imshow(image_data,
                   aspect='auto',
                   interpolation='nearest',
                   cmap=plt.cm.YlOrBr,
                   origin='lower')
    ax.set_xlabel('x [pixels]', fontsize=12)
    ax.set_ylabel(r'y [channels]', fontsize=12)
    ax.set_title("{0} PV diagram. position_angle={1}".format(
        label, position_angle))

    # Colorbar
    colorbar_ax = fig.add_axes([0.9, 0.11, 0.05, 0.77])
    fig.colorbar(im, cax=colorbar_ax, label=r'Jy Beam$^{-1}$')
    colorbar_ax.tick_params(labelsize=10)

    return fig
Exemplo n.º 10
0
paths = pvextractor.pvregions.paths_from_regfile('loop_segment_30kms.reg')

for mol in ("HCN", "HNC", "HCOp", "HC3N", "H2CS303-202", "H2CS303202"):
    for pathno, path in enumerate(paths):
        for fn in (glob.glob("*{0}*image.pbcor.fits".format(mol)) +
                   glob.glob("feathered/Feathered*{0}*.fits".format(mol)) +
                   glob.glob("feathered/Regridded*{0}*fits".format(mol))):

            if any(x in fn for x in ('mask', 'max', 'sum', 'mom', 'pvext')):
                continue

            rcube = (SpectralCube.read(fn).with_spectral_unit(
                u.km / u.s, velocity_convention='radio').spectral_slab(
                    0.0 * u.km / u.s, 160 * u.km / u.s))

            slice = pvextractor.extract_pv_slice(rcube, path)
            slice.writeto(fn.replace(
                ".fits", ".pvextraction_path{0}.fits".format(pathno)),
                          clobber=True)

            F = aplpy.FITSFigure(slice)
            F.show_grayscale()
            F.save(
                fn.replace(".fits",
                           ".pvextraction_path{0}.png".format(pathno)))
            print fn.replace(".fits",
                             ".pvextraction_path{0}.png".format(pathno))
            F.show_contour(
                'SgrB2_a_03_7M.HNC.image.pbcor.pvextraction_path0.fits')
            F.save(
                fn.replace(
Exemplo n.º 11
0
from pvextractor.geometry import Path

jet_endpoints = coordinates.SkyCoord([290.9186, 290.91424]*u.deg, [14.518876,
                                                                   14.517977]*u.deg,
                                     frame='fk5')

xy = Path(jet_endpoints, width=2.8*u.arcsec)
for ii,(fn,stretch) in enumerate((('w51.neii.square.fits','arcsinh'),
                                  ('w51.siv.square.fits','log'),
                                  ('W51north_H77_Outflow_cutout.fits','arcsinh'),
                                  ('H77a_cutout_1.fits','log'),
                                  ('H77a_cutout_2.fits','log'),
                                 )):
    cube = SpectralCube.read(paths.dpath(fn)).with_spectral_unit(u.km/u.s,
                                                                 velocity_convention='radio',
                                                                 rest_value=14128610000.0*u.Hz).spectral_slab(-200*u.km/u.s, 200*u.km/u.s)
    pv = extract_pv_slice(cube.hdu, xy)
    pv.data -= np.nanmin(pv.data) - 1e-3
    fig = pl.figure(ii)
    fig.clf()
    FF = aplpy.FITSFigure(pv, figure=fig)
    FF.show_grayscale(aspect='auto', invert=True, stretch=stretch)
    FF.recenter(0.0021, 65e3, width=0.0042, height=300e3)
    FF._ax1.set_yticklabels([str(float(L.get_text())/1e3) for L in FF._ax1.get_yticklabels()])
    FF._ax1.set_ylabel("Velocity (km/s)")
    FF._ax1.set_xticklabels([str(float(L.get_text())*3600) for L in FF._ax1.get_xticklabels()])
    FF._ax1.set_xlabel("Offset (arcsec)")
    FF.save(paths.fpath('jetpv/{0}.png'.format(fn[:-5])))
    FF.save(paths.fpath('jetpv/{0}.pdf'.format(fn[:-5])))

Exemplo n.º 12
0
    ignore_missing_end=True)

mask = BooleanArrayMask(mask=np.isfinite(hdu[0].data), wcs=WCS(hdu[0].header))

sc = SpectralCube(data=hdu[0].data, wcs=WCS(hdu[0].header), mask=mask)

# Select the region of interest
sc_small = sc[120:300, 156:346, 677:958]

# Ends for the PV slice
# ends = [(107, 74), (151, 76), (220, 54)]
ends = [(105, 70), (145, 80), (227, 28), (238, 1)]

xy = Path(ends, width=10)

pv = extract_pv_slice(sc_small, xy)

p.subplot(121)
p.imshow(sc_small.moment0().value, cmap="binary", origin="lower")
p.plot([i for i, j in ends], [j for i, j in ends], 'b-')

p.subplot(122)
p.imshow(pv.data, cmap="binary", origin="lower")
p.colorbar()

p.show()

hdu.close()

# Now examine a subsection of the region that overlaps with the edge of
# NGC-1333. I'm not sure the instrument that took the data, but it maps
Exemplo n.º 13
0
    e2siored = e2mslab.spectral_slab(74*u.km/u.s, 118*u.km/u.s).moment0()
    e2siored.write('/Users/adam/work/w51/alma/FITS/longbaseline/{line}_74to118kms_e2.fits'.format(line=line), overwrite=True)



    import pvextractor
    from pvextractor.pvregions import paths_from_regions
    import pyregion
    import paths
    reg = pyregion.open(paths.rpath('../regions/e2eoutflow_reference_vector.reg'))
    outflowcoords = paths_from_regions(reg)
    outflowpath = outflowcoords[0]
    outflowpath.width = 0.15*u.arcsec

    extracted = pvextractor.extract_pv_slice(e2slab, outflowpath)

    import aplpy
    FF = aplpy.FITSFigure(extracted)
    FF.show_grayscale(aspect='auto')
    FF.save(paths.fpath('outflows/{line}_PV_e2e.png'.format(line=line)))



    e8cube = SpectralCube.read('/Volumes/passport/alma/w51/longbaseline/W51e8cax.SPW0_ALL_medsub_cutout.fits')
    e8vcube = e8cube.with_spectral_unit(u.km/u.s, rest_value=freq,
                                        velocity_convention='radio')

    e8slab = e8vcube.spectral_slab(-100*u.km/u.s, 210*u.km/u.s)
    e8slab.allow_huge_operations = True
    e8med = e8slab.median(axis=0)
Exemplo n.º 14
0
if pf[0].data.ndim != mywcs.wcs.naxis:
    naxes = ['NAXIS%i' % ii for ii in range(1,mywcs.wcs.naxis+1)]
    # WCS is 1-indexed
    axes_to_keep = [ii+1
                    for ii,nax in enumerate(naxes)
                    if header[nax] > 1]
    mywcs = mywcs.sub(axes_to_keep)
    pf[0].header = mywcs.to_header()


rstringlist = dd.get('regions -system wcs').split("\n")
regions = load_regions_stringlist(rstringlist)
if len(regions) == 0:
    sys.exit("No regions found")

paths = paths_from_regions(regions)

hdu = pvextractor.extract_pv_slice(pf[0], paths[regionid], order=0)

with tempfile.NamedTemporaryFile(suffix='fits', delete=False) as tf:
    hdu.writeto(tf.name)

# it may be possible to do this by
# ds9_pvextract.py $xpa_method | $image
# or any of the commented methods below...
dd.set('frame new')
#print tf.name
dd.set('fits '+tf.name)
#dd.set_pyfits(fits.HDUList(hdu))
#dd.set_np2arr(slc)
Exemplo n.º 15
0
linexy=cube.wcs.wcs_pix2world(linex, liney, 0, 0)
linex=[i for i in linexy[0]]
liney=[i for i in linexy[1]]

if width!=0:
    polyxy=path.sample_polygons(spacing=step, wcs=cube.wcs)
    polyx, polyy=[], []
    for i in range(len(polyxy)):
        polyx+=polyxy[i].x
        polyy+=polyxy[i].y
    polyxy=cube.wcs.wcs_pix2world(polyx, polyy, 0, 0)
    polyx=[i for i in polyxy[0]]
    polyy=[i for i in polyxy[1]]

""" slice export """
slice=extract_pv_slice(cube, path, spacing=step)

slice.data=slice.data.transpose()
keys=['CTYPE', 'CRVAL', 'CDELT', 'CRPIX', 'CUNIT']
for i in range(len(keys)):
    slice.header[keys[i]+'1'], slice.header[keys[i]+'2']=slice.header[keys[i]+'2'], slice.header[keys[i]+'1']
    slice.header.comments[keys[i]+'1'], slice.header.comments[keys[i]+'2']=slice.header.comments[keys[i]+'2'], slice.header.comments[keys[i]+'1']

slice.header['CDELT1']=slice.header['CDELT1']/1e3
slice.header.comments['CDELT1']='[km/s] Coordinate increment at reference point'
slice.header['CUNIT1']='km/s'
slice.header['CRVAL1']=slice.header['CRVAL1']/1e3
slice.header.comments['CRVAL1']='[km/s] Coordinate value at reference point'
if spec!=[]:
    slice.header['CRPIX1']=float(1.0)
    slice.header['CRVAL1']=linexy[2][0]/1e3
Exemplo n.º 16
0
#rp = pyregion.RegionParser()

# have to check for ds9 dropping degenerate axes
if pf[0].data.ndim != mywcs.wcs.naxis:
    naxes = ['NAXIS%i' % ii for ii in range(1, mywcs.wcs.naxis + 1)]
    # WCS is 1-indexed
    axes_to_keep = [ii + 1 for ii, nax in enumerate(naxes) if header[nax] > 1]
    mywcs = mywcs.sub(axes_to_keep)
    pf[0].header = mywcs.to_header()

rstringlist = dd.get('regions -system wcs').split("\n")
regions = load_regions_stringlist(rstringlist)
if len(regions) == 0:
    sys.exit("No regions found")

paths = paths_from_regions(regions)

hdu = pvextractor.extract_pv_slice(pf[0], paths[regionid], order=0)

with tempfile.NamedTemporaryFile(suffix='fits', delete=False) as tf:
    hdu.writeto(tf)

# it may be possible to do this by
# ds9_pvextract.py $xpa_method | $image
# or any of the commented methods below...
dd.set('frame new')
#print tf.name
dd.set('fits ' + tf.name)
#dd.set_pyfits(fits.HDUList(hdu))
#dd.set_np2arr(slc)
                       maxpars=[70, 5, 1500, 1e18, 10000],
                       minpars=[40, 0.1, 50, 1e13, min_background],
                       signal_cut=0,
                       maskmap=absorption_mask,
                       errmap=err.value,
                       multicore=4)
    pcube_cont.write_fit('e2e_CH3CN_Absorption_fits.fits', clobber=True)

from kinematic_analysis_pv_LB import diskycoords, outflowpath
import pvextractor
import pylab as pl

pl.figure(5).clf()
for width in (None, 0.05 * u.arcsec, 0.1 * u.arcsec, 0.15 * u.arcsec):
    diskypath = pvextractor.Path(diskycoords, width)
    extracted_disky = pvextractor.extract_pv_slice(
        pcube_cont.parcube[0:1, :, :], diskypath, wcs=pcube_cont.wcs)

    pl.plot(extracted_disky.data.squeeze(), label=str(width))

pl.xlabel("Offset (pixels)")
pl.ylabel("Velocity (km/s)")
pl.ylim(55, 60)
pl.xlim(855, 890)

pl.legend(loc='best')
pl.savefig(paths.fpath("longbaseline/kinematics/velocity_vs_offset.png"))

pl.figure(6).clf()
diskypath = pvextractor.Path(diskycoords, width=None)
extracted_disky = pvextractor.extract_pv_slice(pcube_cont.parcube[0:1, :, :],
                                               diskypath,
Exemplo n.º 18
0
        cmap.set_bad((1.0,)*3)
    else:
        cmap.set_bad((0.9,0.9,0.9,0.5))


    pvfilename = ('orbits/KDL2014_orbit_on_{0}.fits'.format(molecule))
    if os.path.exists(pvfilename):
        pv = fits.open(pvfilename)[0]
    else:
        # respect_nan = False so that the background is zeros where there is data
        # and nan where there is not data
        # But not respecting nan results in data getting averaged with nan, so we
        # need to respect it and then manually flag (in a rather unreliable
        # fashion!)
        #pv = pvextractor.extract_pv_slice(cube, P, respect_nan=False)
        pv = pvextractor.extract_pv_slice(cube, P, respect_nan=True)
        if not os.path.isdir(os.path.dirname(pvfilename)):
            os.mkdir(os.path.dirname(pvfilename))
        pv.writeto(pvfilename)


    bad_cols = np.isnan(np.nanmax(pv.data, axis=0))
    nandata = np.isnan(pv.data)
    pv.data[nandata & ~bad_cols] = 0
    ok = ~nandata & ~bad_cols

    fig1 = pl.figure(1, figsize=figsize)
    fig1.clf()
    ax = fig1.gca()
    mywcs = WCS(pv.header)
    xext, = mywcs.sub([1]).wcs_pix2world((0,pv.shape[1]), 0)
Exemplo n.º 19
0
def _slice_from_path(x, y, data, attribute, slc):
    """
    Extract a PV-like slice from a cube

    :param x: An array of x values to extract (pixel units)
    :param y: An array of y values to extract (pixel units)
    :param data: :class:`~glue.core.data.Data`
    :param attribute: :claass:`~glue.core.data.Component`
    :param slc: orientation of the image widget that `pts` are defined on

    :returns: (slice, x, y)
              slice is a 2D Numpy array, corresponding to a "PV ribbon"
              cutout from the cube
              x and y are the resampled points along which the
              ribbon is extracted

    :note: For >3D cubes, the "V-axis" of the PV slice is the longest
           cube axis ignoring the x/y axes of `slc`
    """
    from pvextractor import Path, extract_pv_slice
    p = Path(list(zip(x, y)))

    cube = data[attribute]
    dims = list(range(data.ndim))
    s = list(slc)
    ind = _slice_index(data, slc)

    from astropy.wcs import WCS

    if isinstance(data.coords, WCS):
        cube_wcs = data.coords
    else:
        cube_wcs = None

    # transpose cube to (z, y, x, <whatever>)
    def _swap(x, s, i, j):
        x[i], x[j] = x[j], x[i]
        s[i], s[j] = s[j], s[i]

    _swap(dims, s, ind, 0)
    _swap(dims, s, s.index('y'), 1)
    _swap(dims, s, s.index('x'), 2)

    cube = cube.transpose(dims)

    if cube_wcs is not None:
        cube_wcs = cube_wcs.sub([data.ndim - nx for nx in dims[::-1]])

    # slice down from >3D to 3D if needed
    s = tuple([slice(None)] * 3 + [slc[d] for d in dims[3:]])
    cube = cube[s]

    # sample cube
    spacing = 1  # pixel
    x, y = [np.round(_x).astype(int) for _x in p.sample_points(spacing)]

    try:
        result = extract_pv_slice(cube, path=p, wcs=cube_wcs, order=0)
        wcs = WCS(result.header)
    except Exception:  # sometimes pvextractor complains due to wcs. Try to recover
        result = extract_pv_slice(cube, path=p, wcs=None, order=0)
        wcs = None

    data = result.data

    return data, x, y, wcs
        for line, restfreq, velocity_res, spw in line_to_image_list:

            basename = line

            frq = float(restfreq.strip('GHz')) * u.GHz
            vcube = cube.with_spectral_unit(u.km/u.s,
                                            velocity_convention='radio',
                                            rest_value=frq)
            svcube = vcube.spectral_slab((vrange[0]-1)*u.km/u.s,
                                         (vrange[1]+1)*u.km/u.s)
            if svcube.shape[0] <= 1:
                continue

            print("Extracting {0}: {1}".format(line, restfreq))

            extracted = pvextractor.extract_pv_slice(svcube, P)
            #extracted.writeto(outfn, clobber=True)

            ww = wcs.WCS(extracted.header)
            ww.wcs.cdelt[1] /= 1000.0
            ww.wcs.crval[1] /= 1000.0
            ww.wcs.cunit[1] = u.km/u.s
            ww.wcs.cdelt[0] *= 3600
            ww.wcs.cunit[0] = u.arcsec

            fig = pl.figure(1)
            fig.clf()
            ax = fig.add_axes([0.15, 0.1, 0.8, 0.8],projection=ww)
            ax.imshow(extracted.data, cmap='viridis')
            ax.set_xlabel("Offset [\"]")
            ax.set_ylabel("$V_{LSR}$ [km/s]")
                       limitedmin=[T,T,T,T,T],
                       maxpars=[70,5,1500,1e18,10000],
                       minpars=[40,0.1,50,1e13,min_background],
                       signal_cut=0,
                       maskmap=absorption_mask,
                       errmap=err.value, multicore=4)
    pcube_cont.write_fit('e2e_CH3CN_Absorption_fits.fits', clobber=True)

from kinematic_analysis_pv_LB import diskycoords, outflowpath
import pvextractor
import pylab as pl

pl.figure(5).clf()
for width in (None, 0.05*u.arcsec, 0.1*u.arcsec, 0.15*u.arcsec):
    diskypath = pvextractor.Path(diskycoords, width)
    extracted_disky = pvextractor.extract_pv_slice(pcube_cont.parcube[0:1,:,:], diskypath, wcs=pcube_cont.wcs)

    pl.plot(extracted_disky.data.squeeze(), label=str(width))

pl.xlabel("Offset (pixels)")
pl.ylabel("Velocity (km/s)")
pl.ylim(55,60)
pl.xlim(855,890)

pl.legend(loc='best')
pl.savefig(paths.fpath("longbaseline/kinematics/velocity_vs_offset.png"))

pl.figure(6).clf()
diskypath = pvextractor.Path(diskycoords, width=None)
extracted_disky = pvextractor.extract_pv_slice(pcube_cont.parcube[0:1,:,:],
                                               diskypath, wcs=pcube_cont.wcs)
Exemplo n.º 22
0
            'NGC4448': (-999.,900.),
            'NGC4559': (-999.,1000.),
            'NGC4631': (-999.,850.),
            'NGC5055': (200.,800.),
            'NGC5229': (-999.,470.),
            'UGC2082': (550.,850.),
            'UGC4278': (400.,700.),
            'UGC7774': (350.,680.)}

for galaxy in galaxies:
    pv_path = PathFromCenter(center=gvals[galaxy]['CENTER'],
        length=gvals[galaxy]['DIAMETER']*u.arcsec,
        angle=gvals[galaxy]['PA']*u.deg,
        width=1.*u.arcsec)

    pv_slice = extract_pv_slice(galaxy+'-LR-cube.fits', pv_path)

    hdr = pv_slice.header

    vaxis = (np.arange(hdr['NAXIS2'])+1.-hdr['CRPIX2'])*hdr['CDELT2']+hdr['CRVAL2']
    vaxis /= 1000.
    if galaxy in velrange.keys():
        print 'REDUCING VELOCITY RANGE'
        vmin, vmax = velrange[galaxy]
        if vmin < -998.: vmin = np.min(vaxis)
        gvp = np.where(np.logical_and(vaxis<=vmax,vaxis>=vmin))
        print np.min(gvp), np.max(gvp), len(vaxis)
        data = pv_slice.data
        newdata = data[gvp,:]
        pv_slice.data = newdata
        voffset = np.min(gvp)
Exemplo n.º 23
0
    for molecule,fn in zip(molecules[-4:],filenames[-4:]):
        log.info(molecule)
        cube = spectral_cube.SpectralCube.read(fn)

        if weight:

            wcube = (spectral_cube.SpectralCube.read(hpath('APEX_H2CO_303_202_smooth_bl.fits'))
                     if 'smooth' in fn
                     else spectral_cube.SpectralCube.read(hpath('APEX_H2CO_303_202_bl.fits')))
            if cube.shape != wcube.shape:
                log.info("Not weighting {0}".format(fn))
                continue
            weighted = copy.copy(cube)
            weighted._data = wcube._data * cube._data

            pv1 = pvextractor.extract_pv_slice(weighted, P, respect_nan=True)
            pv2 = pvextractor.extract_pv_slice(wcube.with_mask(cube.mask), P, respect_nan=True)
            pv = copy.copy(pv1)
            pv.data = pv1.data/pv2.data
        else:
            # respect_nan = False so that the background is zeros where there is data
            # and nan where there is not data
            # But not respecting nan results in data getting averaged with nan, so we
            # need to respect it and then manually flag (in a rather unreliable
            # fashion!)
            #pv = pvextractor.extract_pv_slice(cube, P, respect_nan=False)
            pv = pvextractor.extract_pv_slice(cube, P, respect_nan=True)
        bad_cols = np.isnan(np.nanmax(pv.data, axis=0))
        nandata = np.isnan(pv.data)
        pv.data[nandata & ~bad_cols] = 0
Exemplo n.º 24
0
from astropy import units as u
from astropy.coordinates import FK5
import numpy as np

ra = [278.3947241,278.3928173,278.3896708,278.3882779,278.387925,278.3874497,278.3881945,278.3888875]
dec= [-8.644493589,-8.645027916,-8.646443333,-8.648562055,-8.649796945,-8.651193056,-8.65423175,-8.655833333]

for i in range(len(ra)-1):
	dra  = ra[i+1] - ra[i]
	ddec = dec[i+1] - dec[i]
	sepa = np.sqrt((dra*np.cos(dec[i]/180.*np.pi))**2 + (ddec)**2)
	angle = np.arctan(ddec / (dra*np.cos(dec[i]/180.*np.pi))) / np.pi * 180.
	sepa *= 3600.
	sepa_pix = sepa/0.8
	sepa_pc = sepa/3600./180.*np.pi*4600.
	print "Separation between points: %.2f arcsec or %.2f pixels" % (sepa, sepa_pix)
	print "Separation between points: %.2f pc" % (sepa_pc)
	print "Position angles of segments: %.2f deg" % (90 - angle)

g = FK5(ra * u.deg, dec * u.deg)

path0 = Path(g, width=5 * u.arcsec)

slice0 = extract_pv_slice('18308_11_line.fits', path0) 

slice0.writeto('I18308_11_slice.fits',overwrite=True)

slice1 = extract_pv_slice('18308_22_line.fits', path0) 

slice1.writeto('I18308_22_slice.fits',overwrite=True)
Exemplo n.º 25
0
def plot_pv_diagram(image_path, outpath, coords=None, ext='.png', save=False):
    """
    F**k Miriad and CASA, let's just use a package.

    Args: image_path (str): path to fits image, including extension.
          coords (tuple of tuples): if you have x and y values for the
                                    disk axis, enter them.
    """

    # Not all the machines have this package installed,
    # so don't run it unless necessary.
    from pvextractor import extract_pv_slice
    from pvextractor import Path as PVPath
    # Can use this to test for points:
    if coords is None:
        keep_trying = True
        # For HCN
        xs, ys = [38, 57], [55, 45]

        while keep_trying:
            plt.close()
            print("Find coordinates for a line across the disk axis:")

            # Import and crop the data, 70 pixels in each direction.
            image_data_3d = fits.getdata(image_path).squeeze()[:, 80:176,
                                                               80:176]
            # Make a quick moment map
            image_data = np.sum(image_data_3d, axis=0)

            # Plot
            plt.contourf(image_data, 50, cmap='BrBG')
            plt.colorbar(extend='both')
            plt.contour(image_data, colors='k', linewidths=0.2)
            plt.plot(xs, ys, '-k')
            plt.show(block=False)
            response = input('\nWant to try again?\n[y/n]: ').lower()
            keep_trying = True if response == 'y' or response == 'yes' else False
            if keep_trying:
                xs_raw = input(
                    'Enter the x coordinates (previous attempt: {}):\n[x1, x2]: '
                    .format(xs))
                xs = tuple(int(x.strip()) for x in xs_raw.split(','))

                ys_raw = input(
                    'Enter the x coordinates (previous attempt: {}):\n[y1, y2]: '
                    .format(ys))
                ys = tuple(int(x.strip()) for x in ys_raw.split(','))
    else:
        xs, ys = coords

    path = PVPath([(xs[0], ys[0]), (xs[1], ys[1])])
    pv_data = extract_pv_slice(image_data_3d, path).data.T

    # Make the plot.
    plt.close()
    plt.clf()
    fig, (ax_image, ax_pv) = plt.subplots(1,
                                          2,
                                          figsize=(10, 5),
                                          gridspec_kw={'width_ratios': [2, 2]})

    ax_image.contourf(image_data, 50, cmap='BrBG')
    #   ax_image.colorbar(extend='both')
    ax_image.contour(image_data, colors='k', linewidths=0.2)
    ax_image.plot(xs, ys, '-k')

    ax_pv.contourf(pv_data, 30, cmap='inferno')
    # ax_pv.colorbar(extend='both')
    ax_pv.contour(pv_data, 30, colors='k', linewidths=0.1)

    # Image aesthetics
    pixel_to_AU = 0.045 * 389  # arcsec/pixel * distance -> AU
    pixel_to_as = 0.045
    pv_ts = np.array(ax_pv.get_xticks().tolist()) * pixel_to_AU
    # pv_ticks = np.linspace(min(pv_ts), max(pv_ts), 5) - np.mean(pv_ts)

    start, end = ax_pv.get_xlim()
    pv_tick_labels = (np.linspace(start, end, 5) -
                      np.mean([start, end])) * pixel_to_AU
    pv_tick_labels = [int(tick) for tick in pv_tick_labels]

    vmin, vmax = ax_pv.get_ylim()
    vel_tick_labels = np.linspace(vmin, vmax, 5) - np.mean([vmin, vmax])
    vel_tick_labels = [int(tick) for tick in vel_tick_labels]

    ax_pv.set_xticklabels(pv_tick_labels)
    ax_pv.set_yticklabels(vel_tick_labels)
    ax_pv.set_ylabel("Velocity (km/s)", weight='bold', rotation=270)
    ax_pv.set_xlabel("Position Offset (AU)", weight='bold')
    ax_pv.yaxis.tick_right()
    ax_pv.yaxis.set_label_position("right")

    start, end = ax_image.get_xlim()
    image_xtick_labels = (np.linspace(start, end, 5) -
                          np.mean([start, end])) * pixel_to_AU
    image_xtick_labels = [int(tick) for tick in image_xtick_labels]

    start, end = ax_image.get_ylim()
    image_ytick_labels = (np.linspace(start, end, 5) -
                          np.mean([start, end])) * pixel_to_AU
    image_ytick_labels = [int(tick) for tick in image_ytick_labels]

    x_ts = np.array(ax_image.get_xticks().tolist()) * pixel_to_AU
    # image_xticks = np.linspace(min(x_ts), max(x_ts), 5) - np.mean(x_ts)
    # image_xtick_labels = [int(tick) for tick in image_xticks]
    #
    y_ts = np.array(ax_image.get_yticks().tolist()) * pixel_to_AU
    # image_yticks = np.linspace(min(y_ts), max(y_ts), 5) - np.mean(y_ts)
    # image_ytick_labels = [int(tick) for tick in image_yticks]

    # ax_image.set_xticklabels(x_ts)
    # ax_image.set_yticklabels(y_ts)
    ax_image.set_xticklabels(image_xtick_labels)
    ax_image.set_yticklabels(image_ytick_labels)
    ax_image.set_xlabel("Position Offset (AU)", weight='bold')
    ax_image.set_ylabel("Position Offset (AU)", weight='bold')

    mol = get_line(image_path).upper()
    plt.suptitle('Moment Map and PV Diagram for {}'.format(mol), weight='bold')
    # plt.tight_layout()

    if save:
        plt.savefig(outpath + ext)
        print("Saved PV diagram to {}{}".format(outpath, ext))
    else:
        print("Showing:")
        plt.show(block=False)
Exemplo n.º 26
0
cube = SpectralCube.read('FITS/Orion_NWSE_12CO2-1_merge_7m_12m.image.fits')
mask = (cube.spectral_axis < 3*u.km/u.s) | (cube.spectral_axis > 14.5*u.km/u.s)
cube = cube.with_mask(mask[:,None,None])
mx = cube.max(axis=0)
med = cube.median(axis=0)
mx = mx - med


pl.close(1)

for ii,(path,theta) in enumerate(zip(paths, angles)):
    outfilename = "pvdiagrams/NWSE_rotation_{0:0.4g}.fits".format(theta)
    if os.path.exists(outfilename):
        hdu = fits.open(outfilename)[0]
    else:
        hdu = pvextractor.extract_pv_slice(cube=cube, path=path)
        hdu.writeto(outfilename)
    print(theta,outfilename)

    pl.figure(1, figsize=(12,12)).clf()
    F = aplpy.FITSFigure(hdu, figure=pl.figure(1), subplot=[0.1, 0.6, 0.8, 0.35])
    F.show_grayscale()
    F.set_title("Rotation {0:0.4g} degrees".format(theta))
    
    F2 = aplpy.FITSFigure(mx.hdu, figure=pl.figure(1), subplot=[0.25,0.05, 0.5, 0.45])
    F2.show_grayscale()
    F2.show_lines([np.array([path.ra.deg, path.dec.deg])], color='r')
    F2.recenter(center.ra, center.dec, radius=(1.1*u.arcmin).to(u.deg).value)

    F.save('pvdiagrams/NWSE_rotation_{0:04d}.png'.format(ii), dpi=300)
paths = pvextractor.pvregions.paths_from_regfile('loop_segment_30kms.reg')

for mol in ("HCN","HNC","HCOp","HC3N","H2CS303-202","H2CS303202"):
    for pathno,path in enumerate(paths):
        for fn in (glob.glob("*{0}*image.pbcor.fits".format(mol)) +
                   glob.glob("feathered/Feathered*{0}*.fits".format(mol)) +
                   glob.glob("feathered/Regridded*{0}*fits".format(mol))):

            if any(x in fn for x in ('mask','max','sum','mom','pvext')):
                continue

            rcube = (SpectralCube.read(fn)
                     .with_spectral_unit(u.km/u.s, velocity_convention='radio')
                     .spectral_slab(0.0*u.km/u.s, 160*u.km/u.s))

            slice = pvextractor.extract_pv_slice(rcube, path)
            slice.writeto(fn.replace(".fits",".pvextraction_path{0}.fits".format(pathno)),
                          clobber=True)

            F = aplpy.FITSFigure(slice)
            F.show_grayscale()
            F.save(fn.replace(".fits",".pvextraction_path{0}.png".format(pathno)))
            print fn.replace(".fits",".pvextraction_path{0}.png".format(pathno))
            F.show_contour('SgrB2_a_03_7M.HNC.image.pbcor.pvextraction_path0.fits')
            F.save(fn.replace(".fits",".pvextraction_path{0}_contourHNCACA.png".format(pathno)))
            F.remove_layer('contour_set_1')
            F.show_contour('feathered/Feathered_HNC.pvextraction_path0.fits')
            F.save(fn.replace(".fits",".pvextraction_path{0}_contourHNCFeath.png".format(pathno)))

            for ii in pl.get_fignums():
                pl.close(ii)
Exemplo n.º 28
0
        fc='none',
        #transform=ax.transData,
        clip_on=True,  #clip_box=ax.bbox,
        wcs=cube.data.coords.wcs)
    for patch in patches:
        patch.set_linewidth(0.5)
        patch.set_alpha(0.5)
        patch.zorder = 50
    patchcoll = matplotlib.collections.PatchCollection(patches,
                                                       match_original=True)
    patchcoll.zorder = 10
    ax.add_collection(patchcoll)
    ax.axis([x.min(), x.max(), y.min(), y.max()])

    pv = pvextractor.extract_pv_slice(cube.data['PRIMARY'],
                                      P,
                                      wcs=cube.data.coords.wcs)
    pvwidget = PVSliceWidget(image=pv.data,
                             wcs=wcs.WCS(pv.header),
                             image_client=cube_viewer,
                             x=x,
                             y=y,
                             interpolation='nearest')
    pv_viewer = app.add_widget(pvwidget, label="Orbit PV Slice")
    ax2 = pvwidget.axes

    dl = (table['l'][1:] - table['l'][:-1])
    db = (table['b'][1:] - table['b'][:-1])
    dist = (dl**2 + db**2)**0.5
    cdist = np.zeros(dist.size + 1) * u.deg
    cdist[1:] = dist.cumsum() * u.deg
        assert 'cutout' in fn
        basename = ".".join([os.path.basename(namesplit[0]),
                             namesplit[1],
                             name+"_diskpv",
                             "fits"])
        outfn = paths.dpath(os.path.join("12m/pv/", basename))

        cube = SpectralCube.read(fn)
        cube.allow_huge_operations=True
        cube.beam_threshold = 5
        med = cube.median(axis=0)
        medsub = cube - med

        P = pvextractor.Path(diskycoords, 0.2*u.arcsec)
        extracted = pvextractor.extract_pv_slice(medsub, P)
        #extracted.writeto(outfn, clobber=True)

        ww = wcs.WCS(extracted.header)
        ww.wcs.cdelt[1] /= 1000.0
        ww.wcs.crval[1] /= 1000.0
        ww.wcs.cunit[1] = u.km/u.s
        ww.wcs.cdelt[0] *= 3600
        ww.wcs.cunit[0] = u.arcsec

        fig = pl.figure(1)
        fig.clf()
        ax = fig.add_axes([0.15, 0.1, 0.8, 0.8],projection=ww)
        ax.imshow(extracted.data, cmap='viridis')
        ax.set_xlabel("Offset [\"]")
        ax.set_ylabel("$V_{LSR}$ [km/s]")
Exemplo n.º 30
0
                                     frame='fk5')

xy = Path(jet_endpoints, width=2.8 * u.arcsec)
for ii, (fn, stretch) in enumerate((
    ('w51.neii.square.fits', 'arcsinh'),
    ('w51.siv.square.fits', 'log'),
    ('W51north_H77_Outflow_cutout.fits', 'arcsinh'),
    ('H77a_cutout_1.fits', 'log'),
    ('H77a_cutout_2.fits', 'log'),
)):
    cube = SpectralCube.read(paths.dpath(fn)).with_spectral_unit(
        u.km / u.s,
        velocity_convention='radio',
        rest_value=14128610000.0 * u.Hz).spectral_slab(-200 * u.km / u.s,
                                                       200 * u.km / u.s)
    pv = extract_pv_slice(cube.hdu, xy)
    pv.data -= np.nanmin(pv.data) - 1e-3
    fig = pl.figure(ii)
    fig.clf()
    FF = aplpy.FITSFigure(pv, figure=fig)
    FF.show_grayscale(aspect='auto', invert=True, stretch=stretch)
    FF.recenter(0.0021, 65e3, width=0.0042, height=300e3)
    FF._ax1.set_yticklabels(
        [str(float(L.get_text()) / 1e3) for L in FF._ax1.get_yticklabels()])
    FF._ax1.set_ylabel("Velocity (km/s)")
    FF._ax1.set_xticklabels(
        [str(float(L.get_text()) * 3600) for L in FF._ax1.get_xticklabels()])
    FF._ax1.set_xlabel("Offset (arcsec)")
    FF.save(paths.fpath('jetpv/{0}.png'.format(fn[:-5])))
    FF.save(paths.fpath('jetpv/{0}.pdf'.format(fn[:-5])))
        #('w51_12CO_21_contsub_hires.image.pbcor.fits', 'arcsinh', -0.01, 0.2,
        # 'e8'),
)):

    pars = parameters[source]

    cube = SpectralCube.read(paths.dpath(fn))
    cube = cube.with_spectral_unit(u.km / u.s, velocity_convention='radio')
    cube = cube.spectral_slab(-200 * u.km / u.s, 200 * u.km / u.s)

    outname = os.path.split('{0}_{1}.{{extension}}'.format(fn[:-5],
                                                           source))[-1]

    outpath_pv = paths.dpath('pv/' + outname.format(extension='fits'))
    if not os.path.exists(outpath_pv):
        pv = extract_pv_slice(cube.hdu, pars['path'])
        #pv.data -= np.nanmin(pv.data) - 1e-3
        pv.writeto(outpath_pv, clobber=True)
    else:
        pv = fits.open(outpath_pv)[0]

    origin = offset_to_point(pars['origin'].ra.deg, pars['origin'].dec.deg,
                             pars['path'])

    fig = pl.figure(ii)
    fig.clf()
    FF = aplpy.FITSFigure(pv, figure=fig)
    FF.show_grayscale(aspect='auto',
                      invert=True,
                      stretch=stretch,
                      vmin=vmin,
Exemplo n.º 32
0
    #ax.plot(table['l'], table['b'], 'r-', linewidth=2, alpha=0.5)
    #ax.plot(x, y, 'r-', linewidth=2, alpha=0.5)
    patches = P.to_patches(1, ec='red', fc='none',
                           #transform=ax.transData,
                           clip_on=True, #clip_box=ax.bbox,
                           wcs=cube.data.coords.wcs)
    for patch in patches:
        patch.set_linewidth(0.5)
        patch.set_alpha(0.5)
        patch.zorder = 50
    patchcoll = matplotlib.collections.PatchCollection(patches, match_original=True)
    patchcoll.zorder=10
    ax.add_collection(patchcoll)
    ax.axis([x.min(),x.max(),y.min(),y.max()])

    pv = pvextractor.extract_pv_slice(cube.data['PRIMARY'], P, wcs=cube.data.coords.wcs)
    pvwidget = PVSliceWidget(image=pv.data, wcs=wcs.WCS(pv.header),
                             image_client=cube_viewer, 
                             x=x, y=y,
                             interpolation='nearest')
    pv_viewer = app.add_widget(pvwidget, label="Orbit PV Slice")
    ax2 = pvwidget.axes

    dl = (table['l'][1:]-table['l'][:-1])
    db = (table['b'][1:]-table['b'][:-1])
    dist = (dl**2+db**2)**0.5
    cdist = np.zeros(dist.size+1) * u.deg
    cdist[1:] = dist.cumsum() * u.deg
    #pixscale = ((x[1]-x[0])**2+(y[1]-y[0])**2)**0.5
    pixscale = wcs.utils.celestial_pixel_scale(cube.data.coords.wcs)
    spwcs = cube.data.coords.wcs.sub([wcs.WCSSUB_SPECTRAL])
            basename = ".".join([os.path.basename(namesplit[0]),
                                 namesplit[1],
                                 name+"_diskpv",
                                 "fits"])
            outfn = paths.dpath(os.path.join("12m/pv/", basename))

            print("Extracting {0} {2}: {1}".format(fn, direction, name))

            cube = SpectralCube.read(fn)
            cube.allow_huge_operations=True
            cube.beam_threshold = 5
            med = cube.median(axis=0)
            medsub = cube - med

            extraction_path = pvextractor.Path(diskycoords, 0.2*u.arcsec)
            extracted = pvextractor.extract_pv_slice(medsub, extraction_path)
            #extracted.writeto(outfn, clobber=True)

            ww = wcs.WCS(extracted.header)
            ww.wcs.cdelt[1] /= 1000.0
            ww.wcs.crval[1] /= 1000.0
            ww.wcs.cunit[1] = u.km/u.s
            ww.wcs.cdelt[0] *= 3600
            ww.wcs.cunit[0] = u.arcsec

            fig = pl.figure(1)
            fig.clf()
            ax = fig.add_axes([0.15, 0.1, 0.8, 0.8],projection=ww)
            ax.imshow(extracted.data, cmap='viridis')
            ax.set_xlabel("Offset [\"]")
            ax.set_ylabel("$V_{LSR}$ [km/s]")
Exemplo n.º 34
0
mask = BooleanArrayMask(mask=np.isfinite(hdu[0].data), wcs=WCS(hdu[0].header))

sc = SpectralCube(data=hdu[0].data, wcs=WCS(hdu[0].header),
                  mask=mask)

# Select the region of interest
sc_small = sc[120:300, 156:346, 677:958]

# Ends for the PV slice
# ends = [(107, 74), (151, 76), (220, 54)]
ends = [(105, 70), (145, 80), (227, 28), (238, 1)]

xy = Path(ends, width=10)

pv = extract_pv_slice(sc_small, xy)

p.subplot(121)
p.imshow(sc_small.moment0().value, cmap="binary", origin="lower")
p.plot([i for i, j in ends], [j for i, j in ends], 'b-')

p.subplot(122)
p.imshow(pv.data, cmap="binary", origin="lower")
p.colorbar()

p.show()

hdu.close()

# Now examine a subsection of the region that overlaps with the edge of
# NGC-1333. I'm not sure the instrument that took the data, but it maps
Exemplo n.º 35
0
                basename = line

                frq = float(restfreq.strip('GHz')) * u.GHz
                vcube = cube.with_spectral_unit(u.km/u.s,
                                                velocity_convention='radio',
                                                rest_value=frq)
                svcube = vcube.spectral_slab((vrange[0]-1)*u.km/u.s,
                                             (vrange[1]+1)*u.km/u.s)
                if svcube.shape[0] <= 5:
                    print("SKIPPING {3} {0} {2}: {1}".format(line, restfreq, direction, name))
                    continue

                print("Extracting {3} {0} {2}: {1}".format(line, restfreq, direction, name))

                extracted = pvextractor.extract_pv_slice(svcube, extraction_path)
                #extracted.writeto(outfn, clobber=True)

                ww = wcs.WCS(extracted.header)
                ww.wcs.cdelt[1] /= 1000.0
                ww.wcs.crval[1] /= 1000.0
                ww.wcs.cunit[1] = u.km/u.s
                ww.wcs.cdelt[0] *= 3600
                ww.wcs.cunit[0] = u.arcsec

                fig = pl.figure(1)
                fig.clf()
                ax = fig.add_axes([0.15, 0.1, 0.8, 0.8],projection=ww)
                ax.imshow(extracted.data, cmap='viridis', vmin=-0.005)
                ax.set_xlabel("Offset [\"]")
                ax.set_ylabel("$V_{LSR}$ [km/s]")
Exemplo n.º 36
0
        log.info(molecule)
        cube = spectral_cube.SpectralCube.read(fn)

        if weight:

            wcube = (spectral_cube.SpectralCube.read(
                hpath('APEX_H2CO_303_202_smooth_bl.fits'))
                     if 'smooth' in fn else spectral_cube.SpectralCube.read(
                         hpath('APEX_H2CO_303_202_bl.fits')))
            if cube.shape != wcube.shape:
                log.info("Not weighting {0}".format(fn))
                continue
            weighted = copy.copy(cube)
            weighted._data = wcube._data * cube._data

            pv1 = pvextractor.extract_pv_slice(weighted, P, respect_nan=True)
            pv2 = pvextractor.extract_pv_slice(wcube.with_mask(cube.mask),
                                               P,
                                               respect_nan=True)
            pv = copy.copy(pv1)
            pv.data = pv1.data / pv2.data
        else:
            # respect_nan = False so that the background is zeros where there is data
            # and nan where there is not data
            # But not respecting nan results in data getting averaged with nan, so we
            # need to respect it and then manually flag (in a rather unreliable
            # fashion!)
            #pv = pvextractor.extract_pv_slice(cube, P, respect_nan=False)
            pv = pvextractor.extract_pv_slice(cube, P, respect_nan=True)
        bad_cols = np.isnan(np.nanmax(pv.data, axis=0))
        nandata = np.isnan(pv.data)
Exemplo n.º 37
0
                    header[kw+"2"] = header[kw+"3"]
                    del header[kw+"3"]
                header['CTYPE1'] = 'OFFSET'
                header = pvextractor.utils.wcs_slicing.slice_wcs(WCS(header),
                                                                 spatial_scale=7.2*u.arcsec).to_header()
                pv = fits.PrimaryHDU(data=pv1/pv2,
                                     header=header)
                pv2hdu = fits.PrimaryHDU(data=pv2, header=header)
            else:
                # respect_nan = False so that the background is zeros where there is data
                # and nan where there is not data
                # But not respecting nan results in data getting averaged with nan, so we
                # need to respect it and then manually flag (in a rather unreliable
                # fashion!)
                #pv = pvextractor.extract_pv_slice(cube, P, respect_nan=False)
                pv = pvextractor.extract_pv_slice(cube, P, respect_nan=True)
            if not os.path.isdir(os.path.dirname(pvfilename)):
                os.mkdir(os.path.dirname(pvfilename))
            pv.writeto(pvfilename)


        bad_cols = np.isnan(np.nanmax(pv.data, axis=0))
        nandata = np.isnan(pv.data)
        pv.data[nandata & ~bad_cols] = 0
        ok = ~nandata & ~bad_cols

        if 'TemperatureFromRatio' in molecule:
            pv.data[ok] = pwtem(pv.data[ok])

        fig1 = pl.figure(1, figsize=figsize)
        fig1.clf()
LSB = SpectralCube.read(LSB_file)
USB = SpectralCube.read(USB_file)


###################################################################################################
# generate pV in pvextractor
###################################################################################################

from pvextractor import PathFromCenter
from pvextractor import extract_pv_slice

full = PathFromCenter(center=kin_center, length=60*u.arcsec, angle=disk_PA, width=30*u.arcsec)
maj  = PathFromCenter(center=kin_center, length=60*u.arcsec, angle=disk_PA, width=1*u.arcsec)

LSB_pV_full = extract_pv_slice(LSB, full)
LSB_pV_maj  = extract_pv_slice(LSB, maj)
USB_pV_full = extract_pv_slice(USB, full)
USB_pV_maj  = extract_pv_slice(USB, maj)

# offset is in degrees, frequency in Hz
# convert to reasonable units
# shift offset axis so that 0 corresponds to the kinematic center
for h in [LSB_pV_full.header, LSB_pV_maj.header, USB_pV_full.header, USB_pV_maj.header]:
    h['crval1'] *= 60*60
    h['cdelt1'] *= 60*60
    h['cunit1'] =  'arcsec'
    h['crval2'] /= 1e9
    h['cdelt2'] /= 1e9
    h['cunit2'] =  'GHz'
    h['crval1'] = 0.
Exemplo n.º 39
0
        83.77088618, 83.79621755, 83.82001665, 83.84612392, 83.8783804,
        83.91332917, 83.95142695, 83.98952916, 84.0308125, 84.07400417,
        84.11910176, 84.1642031
    ] * u.deg, [
        -4.876200218, -4.879461026, -4.897820323, -4.915411506, -4.93299871,
        -4.965857804, -4.99067018, -5.033833723, -5.076613716, -5.123974925,
        -5.173573767, -5.222459592, -5.271344718, -5.318700697, -5.36452826,
        -5.412955261, -5.461988054, -5.510106789, -5.555931851, -5.605577113,
        -5.6519109, -5.701555547, -5.752730272, -5.801156183, -5.84927762,
        -5.897401317, -5.940943148, -5.986011267, -6.029551074, -6.068507208,
        -6.103567778, -6.135131552, -6.166692778, -6.195094167, -6.219704167,
        -6.240522195, -6.261336664
    ] * u.deg)
    path4 = Path(fk, width=6 * u.arcmin)
    slice3 = extract_pv_slice(
        '/Users/shuokong/GoogleDrive/13co/products/regrid_12co_specsmooth_0p25_mask_imfit_13co_pix_2_Tmb.fits',
        path4)
    slice3.writeto('my_slice.fits')

import aplpy
import matplotlib.pyplot as plt
fig = plt.figure()
gc = aplpy.FITSFigure('my_slice.fits', dimensions=[0, 1], figure=fig, hdu=0)
gc.show_colorscale(aspect='auto')

gc.ticks.set_xspacing(21.)
gc.ticks.set_minor_frequency(7)
gc.axis_labels.set_ytext('Velocity (km/s)')
gc.ticks.show()
gc.ticks.set_color('black')
gc.ticks.set_length(10)
Exemplo n.º 40
0
                    os.path.join(
                        'pv',
                        os.path.split(
                            fn.replace(
                                ".image.pbcor.fits",
                                "_medsub_diskpv_{0}.fits".format(width)))[-1]))
                if not os.path.exists(outfn):
                    # width = 0.05 arcsec encompasses the disk; however, most
                    # of the actual line emission comes from just above/below...
                    #extraction_path = pvextractor.Path(diskycoords, width=0.05*u.arcsec)
                    extraction_path = pvextractor.Path(diskycoords,
                                                       width=width * u.arcsec)
                    log.info(
                        "Beginning extraction of path with width {0} for {1}".
                        format(extraction_path.width, outfn))
                    extracted = pvextractor.extract_pv_slice(
                        medsub, extraction_path)
                    log.info("Writing to {0}".format(outfn))
                    extracted.writeto(outfn, overwrite=True)

                for linename, linefreq in disk_lines.items():
                    print(linename, width, fnt, spw, time.time() - t0)

                    pl.close('all')

                    band = 'B' + bandre.search(fnt).groups()[0]

                    if 'robust' in fn:
                        robustnum = robustnumre.search(fn).groups()[0]
                        basename = (
                            "{0}_{1}_{4}_robust{2}_diskpv_{3}.fits".format(
                                name, linename, robustnum, width, band))
Exemplo n.º 41
0
    rotation_axis_len = 50
    pv_path_1 = (source_position_px[0],
                 source_position_px[1] - rotation_axis_len / 2.0
                 )  # (x, y) pixel values
    pv_path_2 = (source_position_px[0],
                 source_position_px[1] + rotation_axis_len / 2.0
                 )  # (x, y) pixel values

    # The path defines the line, whereupon normal
    # dimension is collapsed. I.e. the path line defines the offset direction
    # vector in the pv diagram.

    image_path = Path([pv_path_1, pv_path_2])
    data_cube, hdr = load_fits_cube(cube_file)

    hdu = extract_pv_slice(data_cube, image_path)
    save_extracted_pv_slice_hdu(hdu, hdr, PV_file_name)

    n_x = int(hdr['NAXIS1'])
    n_chan = int(hdr['NAXIS2'])

    font_size = 12

    fig = plt.figure()
    ax = fig.add_subplot(1, 1, 1)

    image_data, im_hdr = load_fits_im(PV_file_name)
    im = ax.imshow(image_data,
                   aspect='auto',
                   interpolation='nearest',
                   cmap=plt.cm.YlOrBr,