Ejemplo n.º 1
0
def replace_visibilities_galario(visdataloc,sbmodelloc,modelvisloc):
	#this needs to be open, channel by channel
	modelimage_cube = fits.getdata(sbmodelloc)
	#this can be the same throughout
	modelheader = fits.getheader(sbmodelloc)
	#these need to be peeled, channel by channel for the following
	uu_cube, vv_cube, ww_cube = uvutil.uvload(visdataloc)
	vis_complex_cube, wgt_cube = uvutil.visload(visdataloc)
	#this can be the same throughout
	pcd = uvutil.pcdload(visdataloc)
	#all the following is done channel by channel
	for chan in range(modelimage_cube.shape[0]):
		uu=np.ones((uu_cube.shape[0],uu_cube.shape[1],1,uu_cube.shape[3]))
		vv=np.ones((vv_cube.shape[0],vv_cube.shape[1],1,vv_cube.shape[3]))
		uu[:,:,0,:]=uu_cube[:,:,chan,:]
		vv[:,:,0,:]=vv_cube[:,:,chan,:]
		modelimage=modelimage_cube[chan]
		uushape = uu.shape
		if len(uushape) == 2:
        		npol = uushape[0]
        		nrow = uushape[1]
        		uushape = (npol, 1, nrow)
		uu = uu.flatten()
		vv = vv.flatten()
		uu=uu.copy(order='C')
		vv=vv.copy(order='C')
		modelimage=np.roll(np.flip(modelimage,axis=0),1,axis=0).copy(order='C').byteswap().newbyteorder()
		model_complex = sampleImage(modelimage, np.absolute(modelheader['CDELT1'])/180*np.pi, uu, vv)   # sample_vis.uvmodel(modelimage, modelheader, uu, vv, pcd)
		vis_complex = model_complex.reshape(uushape)
		vis_complex_cube[:,:,chan,:]=vis_complex[:,:,0,:]
		if chan%10==0:	
			print chan
	#modelvisloc='../replaced_visib.uvfits'
	os.system('rm -rf ' + modelvisloc[:-7]+'*')
	cmd = 'cp ' + visdataloc + ' ' + modelvisloc	
	os.system(cmd)
	real = np.real(vis_complex_cube)
	imag = np.imag(vis_complex_cube)
	visfile = fits.open(modelvisloc, mode='update')
	visibilities = visfile[0].data
	visheader = visfile[0].header
	if visheader['NAXIS'] == 7:
	            visibilities['DATA'][:, 0, 0, :, :, :, 0] = real
	            visibilities['DATA'][:, 0, 0, :, :, :, 1] = imag
	elif visheader['NAXIS'] == 6:
	            visibilities['DATA'][:, 0, 0, :, :, 0] = real
	            visibilities['DATA'][:, 0, 0, :, :, 1] = imag
	else:
	            print("Visibility dataset has >7 or <6 axes.  I can't read this.")
	#visibilities['DATA'][:, 0, 0, :, :, 2] = wgt
	visfile[0].data = visibilities
	visfile.flush()
	visfile.close()
Ejemplo n.º 2
0
    def make_model_visibilities(self, cube, testMode=False, loadMode=False):
        model_cont = self.model_cont
        self.modelimage = self.make_kinms_model(cube)
        model = model_cont + self.modelimage
        xpos, ypos = self.xpos_center_padded, self.ypos_center_padded
        model_padded = np.transpose(
            np.pad(model,
                   ((ypos - self.Nypix_small // 2,
                     self.Nypix - ypos - self.Nypix_small // 2),
                    (xpos - self.Nxpix_small // 2,
                     self.Nxpix - xpos - self.Nxpix_small // 2), (0, 0)),
                   mode='constant'), (2, 0, 1))
        if testMode:
            np.save("test.npy", model_padded)
            print("testing")
        if loadMode:
            model_padded = np.load("test.npy")
            print("loading KinMS cube from test.npy")

        modelimage_cube = model_padded
        vis_complex_model = np.copy(self.vis_complex_model_template)
        for chan in range(modelimage_cube.shape[0]):
            uu = np.ones((self.uu_cube.shape[0], self.uu_cube.shape[1], 1,
                          self.uu_cube.shape[3]))
            vv = np.ones((self.vv_cube.shape[0], self.vv_cube.shape[1], 1,
                          self.vv_cube.shape[3]))
            uu[:, :, 0, :] = self.uu_cube[:, :, chan, :]
            vv[:, :, 0, :] = self.vv_cube[:, :, chan, :]
            modelimage = modelimage_cube[chan]
            uushape = uu.shape
            uu = uu.flatten()
            vv = vv.flatten()
            uu = uu.copy(order='C')
            vv = vv.copy(order='C')
            modelimage = np.roll(np.flip(modelimage, axis=0), 1, axis=0).copy(
                order='C')  # .byteswap().newbyteorder()
            model_complex = sampleImage(
                modelimage,
                np.absolute(self.modelheader['CDELT1']) / 180 * np.pi, uu,
                vv)  # this uses galario
            #model_complex = sample_vis.uvmodel(modelimage, modelheader, uu, vv, pcd)
            vis_complex = model_complex.reshape(uushape)
            vis_complex_model[:, :, chan, :] = vis_complex[:, :, 0, :]
        #replace_visibilities('HZ10_spw01_comb.uvfits','my_img_mod.fits','model_visib.uvfits')
        #vis_complex_model,bb  = uvutil.visload('model_visib.uvfits')
        return vis_complex_model
Ejemplo n.º 3
0
def interpolate_model(u, v, freq, model, nthreads=1, dRA=0., dDec=0.):

    double.threads(nthreads)

    real = []
    imag = []

    dxy = (model.x[1] - model.x[0])*arcsec

    for i in range(len(model.freq)):
        vis = double.sampleImage(model.image[:,:,i,0].copy(order='C'), \
                dxy, u, v, dRA=dRA*arcsec, dDec=dDec*arcsec)

        real.append(vis.real.reshape((u.size,1)))
        imag.append(vis.imag.reshape((u.size,1)))

    real = numpy.concatenate(real, axis=1)
    imag = numpy.concatenate(imag, axis=1)

    return Visibilities(u, v, freq, real, imag, numpy.ones(real.shape))
Ejemplo n.º 4
0
def compare_vis_galario(datfile='data/HD163296.CO32.regridded.cen15',modfile='model/testpy_alma',new_weight=[1,],systematic=False,isgas=True,plot_resid=False):
    '''Calculate the raw chi-squared based on the difference between the model and data visibilities.

    :param datfile: (default = 'data/HD163296.CO32.regridded.cen15')
     The base name for the data file. The code reads in the visibilities from datfile+'.vis.fits'

     :param modfile" (default='model/testpy_alma')
     The base name for the model file. The code reads in the visibilities from modfile+'.model.vis.fits'

     :param new_weight:
     An array containing the weights to be used in the chi-squared calculation. This should have the same dimensions as the real and imaginary part of the visibilities (ie Nbas x Nchan)

     :param systematic:
     The systematic weight to be applied. The value sent with this keyword is used to scale the absolute flux level of the model. It is defined such that a value >1 decreases the model and a value <1 increases the model (the model visibilities are divided by the systematic parameter). It is meant to mimic a true flux in the data which is larger or smaller by the fraction systematic (e.g. specifying systematic=1.2 is equivalent to saying that the true flux of the data is 20% brighter than what has been observed, with this scaling applied to the model instead of changing the data)

     :param isgas:
     If the data is line emission then the data has an extra dimension covering the >1 channels. Set this keyword to ensure that the data is read in properly. Conversely, if you are comparing continuum data then set this keyword to False.

'''
    #Limit the multi-threading of Galario (necessary on the computing cluster)
    gdouble.threads(1)

    # - Read in object visibilities
    obj = fits.open(datfile+'.vis.fits')
    freq0 = obj[0].header['crval4']
    u_obj,v_obj = (obj[0].data['UU']*freq0).astype(np.float64),(obj[0].data['VV']*freq0).astype(np.float64)
    vis_obj = (obj[0].data['data']).squeeze()
    if isgas:
        if obj[0].header['telescop'] == 'ALMA':
            if obj[0].header['naxis3'] == 2:
                real_obj = (vis_obj[:,:,0,0]+vis_obj[:,:,1,0])/2.
                imag_obj = (vis_obj[:,:,0,1]+vis_obj[:,:,1,1])/2.
                weight_real = vis_obj[:,:,0,2]
                weight_imag = vis_obj[:,:,1,2]
            else:
                real_obj = vis_obj[::2,:,0]
                imag_obj = vis_obj[::2,:,1]
    else:
        if obj[0].header['telescop'] == 'ALMA':
            if obj[0].header['naxis3'] == 2:
                real_obj = (vis_obj[:,0,0]+vis_obj[:,1,0])/2.
                imag_obj = (vis_obj[:,0,1]+vis_obj[:,1,1])/2.
                weight_real = vis_obj[:,0,2]
                weight_imag = vis_obj[:,1,2]

    obj.close()

    #Generate model visibilities
    model_fits = fits.open(modfile+'.fits')
    model = model_fits[0].data.squeeze()
    nxy,dxy = model_fits[0].header['naxis1'],np.radians(np.abs(model_fits[0].header['cdelt1']))
    model_fits.close()
    if isgas:
        real_model = np.zeros(real_obj.shape)
        imag_model = np.zeros(imag_obj.shape)
        for i in range(real_obj.shape[1]):
            vis = gdouble.sampleImage(np.flipud(model[i,:,:]).byteswap().newbyteorder(),dxy,u_obj,v_obj)
            real_model[:,i] = vis.real
            imag_model[:,i] = vis.imag
    else:
        vis = gdouble.sampleImage(model.byteswap().newbyteorder(),dxy,u_obj,v_obj)
        real_model = vis.real
        imag_model = vis.imag

    if systematic:
        real_model = real_model/systematic
        imag_model = imag_model/systematic

    if len(new_weight) > 1:
        weight_real = new_weight
        weight_imag = new_weight

    weight_real[real_obj==0] = 0.
    weight_imag[imag_obj==0] = 0.
    print('Removed data %i' % ((weight_real ==0).sum()+(weight_imag==0).sum()))

    if plot_resid:
        #Code to plot, and fit, residuals
        #If errors are Gaussian, then residuals should have gaussian shape
        #If error size is correct, residuals will have std=1
        uv = np.sqrt(u_obj**2+v_obj**2)
        use = (weight_real > .05) & (weight_imag>.05)
        diff = np.concatenate((((real_model[use]-real_obj[use])*np.sqrt(weight_real[use])),((imag_model[use]-imag_obj[use])*np.sqrt(weight_imag[use]))))
        diff = diff.flatten()
        n,bins,patches = plt.hist(diff,10000,normed=1,histtype='step',color='k',label='Data',lw=3)
        popt,pcov = curve_fit(gaussian,bins[1:],n)
        y=gaussian(bins,popt[0],popt[1],popt[2])
        print('Gaussian fit parameters (amp,width,center): ',popt)
        print('If errors are properly scaled, then width should be close to 1')
        plt.plot(bins,y,'r--',lw=6,label='gaussuian')
        #slight deviations from gaussian, but gaussian is still the best...
        plt.xlabel('(Model-Data)/$\sigma$',fontweight='bold',fontsize=20)
        ax=plt.gca()
        for tick in ax.xaxis.get_major_ticks():
            tick.label1.set_fontsize(20)
            tick.label1.set_fontweight('bold')
        for tick in ax.yaxis.get_major_ticks():
            tick.label1.set_fontsize(20)
            tick.label1.set_fontweight('bold')

        plt.show()



    chi = ((real_model-real_obj)**2*weight_real).sum() + ((imag_model-imag_obj)**2*weight_imag).sum()
    return chi
Ejemplo n.º 5
0
	def loglike(self,cube):

		'''
		This function calculates the model ln(likelihood).
		Parameters
		----------
		gassigma: float
			The gas dispersion in km/s
		bright_std: float
			The size as gaussian FWHM in arcsec
		vmax: float
			The max velocity in km/s, the asymptote of the arctan
		vel_scale: float
			The radial distance, in arcsec, where velocity goes to vmax/2
		vel_cen: float
			The velocity center in km/s away from central channel, increasing vel_cen moves it to later channels, i.e. same direction as the channel ordering
		inc: float
		 	Inclination, is 0 for face on and 90 for edge-on
		posang: float
			Position angle starting with red emission from horizontal to the right (toward decreasing RA), and increasing counterclockwise (when we have a - in front of vmax). posang near 0, and - in front of vmax, means the emission moves right to left as channels increase. positive posang rotates this pattern toward the north, in a counterclockwise manner
		x_cen, y_cen: (float,float)
			Center position for the disk, they are in arcsec. y_cen actually controls the x-axis and positive means increasing x of center. x_cen controls y axis, and positive means increasing y of center
		intflux: float
			Line integrated flux in Jy km/s
		Returns
		-------
			ln_like+self.offset_lnlike: float
				We offset the ln_like value by a constant to make the number be small enough for Multinest to be able to work with.
		Definition of posang for the rotating disk:
		If velprof=vmax*np.arctan(velrad/vel_scale)/np.pi*2
		posang 0:   to the right
		posang 90: downwards
		posang 180: to the left
		posang 270 (=-90): upward
		If velprof=-vmax*np.arctan(velrad/vel_scale)/np.pi*2
		posang 0:   to the left
		posang 90: upward
		posang 180: to the right
		posang 270 (=-90): downward
		For example: if the emission is moving from left to right, as channels increase (toward lower frequency and higher velocity, red). Then need posang=180 if minus sign in front of vmax.
		'''
		gassigma,bright_std,vmax,vel_scale,vel_cen,inc,posang,x_cen,y_cen,intflux=cube[0],cube[1],cube[2],cube[3],cube[4],cube[5],cube[6],cube[7],cube[8],cube[9]
		model_cont=self.model_cont
		sbprof=np.exp(-self.sbrad**2/2/(bright_std/2.355)**2)
		velprof=vmax*np.arctan(self.velrad/vel_scale)/np.pi*2
		self.modelimage=KinMS(self.xs,
				self.ys,
				self.vs,
				cellSize=self.cellsize,
				dv=self.dv,
				beamSize=0,
				inc=inc,
				gasSigma=gassigma,
				sbProf=sbprof,
				sbRad=self.sbrad,
				velRad=self.velrad,
				velProf=velprof,
				diskThick=0,
				cleanOut=True,
				ra=0,
				dec=0,
				nSamps=self.nsamps,
				posAng=posang,
				intFlux=intflux,
				inClouds=[],
				vLOS_clouds=[],
				flux_clouds=0,
				vSys=0,
				restFreq=115.271e9,
				phaseCen=np.array([x_cen,y_cen]),
				vOffset=vel_cen,
				fixSeed=False,
				vRadial=0,
				vPosAng=0,
				#vPhaseCen=np.array([x_cen,y_cen]), 
				#That ^ was a workaround for a bug in KinMS that has now been fixed 
				returnClouds=False,
				gasGrav=False,
				fileName=False)
		model = model_cont+self.modelimage
		xpos,ypos=self.xpos_center_padded,self.ypos_center_padded
		model_padded=np.transpose(np.pad(model,((ypos-self.Nypix_small/2,self.Nypix-ypos-self.Nypix_small/2),(xpos-self.Nxpix_small/2,self.Nxpix-xpos-self.Nxpix_small/2),(0,0)),mode='constant'),(2,0,1))
		modelimage_cube = model_padded 
		vis_complex_model=np.copy(self.vis_complex_model_template)
		for chan in range(modelimage_cube.shape[0]):
			uu=np.ones((self.uu_cube.shape[0],self.uu_cube.shape[1],1,self.uu_cube.shape[3]))
			vv=np.ones((self.vv_cube.shape[0],self.vv_cube.shape[1],1,self.vv_cube.shape[3]))
			uu[:,:,0,:]=self.uu_cube[:,:,chan,:]
			vv[:,:,0,:]=self.vv_cube[:,:,chan,:]
			modelimage=modelimage_cube[chan]
			uushape = uu.shape
			uu = uu.flatten()
			vv = vv.flatten()
			uu=uu.copy(order='C')  #This
			vv=vv.copy(order='C') #this
			modelimage=np.roll(np.flip(modelimage,axis=0),1,axis=0).copy(order='C')#.byteswap().newbyteorder()    #This
			model_complex = sampleImage(modelimage, np.absolute(self.modelheader['CDELT1'])/180*np.pi, uu, vv)  #this uses galario
			#model_complex = sample_vis.uvmodel(modelimage, modelheader, uu, vv, pcd)
			vis_complex = model_complex.reshape(uushape)
			vis_complex_model[:,:,chan,:]=vis_complex[:,:,0,:]
		#replace_visibilities('HZ10_spw01_comb.uvfits','my_img_mod.fits','model_visib.uvfits')
		#vis_complex_model,bb  = uvutil.visload('model_visib.uvfits')
		vis_complex_model=vis_complex_model.flatten()[self.good_vis]
		def find_param(scale):
			diff_all=np.abs(self.vis_complex_data-vis_complex_model*scale)
			return np.sum(self.wgt_data*diff_all*diff_all)
		ln_like=-0.5*find_param(1)
		print(ln_like)
		return ln_like+self.offset_lnlike
Ejemplo n.º 6
0
# Do the Fourier transform with TrIFT

u, v = numpy.meshgrid(numpy.linspace(-3., 3., 100),
                      numpy.linspace(-3., 3., 100))

u = u.reshape((u.size, ))
v = v.reshape((v.size, ))

vis = trift.trift_cextended(x, y, flux, u, v, 0., 0.)

# Do the Fourier transform with GALARIO.

dxy = xx[0, 1] - xx[0, 0]

vvis = double.sampleImage(fflux, dxy, u, v, origin="lower")

# NOTE: GALARIO appears to be off by the complex conjugate, possibly because
# CASA spits out visibilities that need to be complex conjugated to have the
# proper orientation (see note by Urvashi Rau, relayed by Ian through
# MPoL or Ryan through vis_sample.

vvis = numpy.conj(vvis)

# And do just a standard, numpy fft.

vvvis = numpy.fft.fftshift(numpy.fft.fft2(numpy.fft.ifftshift(fflux[:, ::-1])))

uu = numpy.fft.fftshift(numpy.fft.fftfreq(1024, dxy))
vv = numpy.fft.fftshift(numpy.fft.fftfreq(1024, dxy))
Ejemplo n.º 7
0
    def mcmc(self, nwalk=16, nsteps=10, nthreads=1, burn=5, out_dir=''):
        '''Do the mcmc.
        
        Parameters
        ----------
        nwalk : int
            Number of walkers.
        nsteps : int
            Number of mcmc steps.
        nthreads : int
            Number of threads.
        burn : int
            Number of steps to count as burn in.
        out_dir : str
            Where to put results.
        '''

        sampler = emcee.EnsembleSampler(nwalk,
                                        self.img.n_params,
                                        self.lnprob,
                                        threads=nthreads)

        # initialize the walkers
        pos = [
            self.p0 + self.p0 * 0.1 * np.random.randn(self.img.n_params)
            for i in range(nwalk)
        ]

        # execute the MCMC
        pos, prob, state = sampler.run_mcmc(pos, nsteps)

        model_name = self.img.Dens.model
        if not os.path.exists(out_dir):
            os.mkdir(out_dir)

        # see what the chains look like, skip a burn in period if desired
        fig, ax = plt.subplots(self.img.n_params + 1,
                               2,
                               figsize=(9.5, 5),
                               sharex='col',
                               sharey=False)

        for j in range(nwalk):
            ax[-1, 0].plot(sampler.lnprobability[j, :burn])
            for i in range(self.img.n_params):
                ax[i, 0].plot(sampler.chain[j, :burn, i])
                ax[i, 0].set_ylabel(self.img.params[i])

        for j in range(nwalk):
            ax[-1, 1].plot(sampler.lnprobability[j, burn:])
            for i in range(self.img.n_params):
                ax[i, 1].plot(sampler.chain[j, burn:, i])
                ax[i, 1].set_ylabel(self.img.params[i])

        ax[-1, 0].set_xlabel('burn in')
        ax[-1, 1].set_xlabel('sampling')
        fig.savefig(out_dir + '/chains-' + model_name + '.png')

        # make the corner plot
        fig = corner.corner(sampler.chain[:, burn:, :].reshape(
            (-1, self.img.n_params)),
                            labels=self.img.params,
                            show_titles=True)

        fig.savefig(out_dir + '/corner-' + model_name + '.png')

        # get the median parameters
        self.p = np.median(sampler.chain[:, burn:, :].reshape(
            (-1, self.img.n_params)),
                           axis=0)
        self.s = np.std(sampler.chain[:, burn:, :].reshape(
            (-1, self.img.n_params)),
                        axis=0)
        print('best fit parameters: {}'.format(self.p))

        # recompute the limits for the full rotated image
        self.img.compute_rmax(self.p, image_full=True)

        fig, ax = plt.subplots()
        ax.imshow(self.img.image_full(self.p)[self.img.cc], origin='bottom')
        fig.savefig(out_dir + '/best-' + model_name + '.png')

        # save the chains to file
        np.savez_compressed(out_dir + '/chains-' + model_name + '.npz',
                            sampler.chain, sampler.lnprobability)

        # save the visibilities for subtraction from the data
        vis_mod = gd.sampleImage(self.img.pb * self.img.image(self.p[3:]),
                                 self.dxy,
                                 self.u,
                                 self.v,
                                 dRA=self.p[0] * arcsec,
                                 dDec=self.p[1] * arcsec,
                                 PA=np.deg2rad(self.p[2]))
        np.save(out_dir + '/vis-' + model_name + '.npy', vis_mod)