Fit a Gaussian to Visibility data and plot it over the data
B.Mason, K.Ward-Duong, & J.Patience July 2015 developed in CASA 4.2.2
This CASA guide illustrates how to run UVMODELFIT to fit a single Gaussian component to UV data (i.e. the raw visibilities); and subsequently how to make a plot of the binned, "azimuthally" averaged (in UV space) UV data together with the fitted model. In broad outlines, the steps required are:
1 Estimate the peak location of emission. shift the phase center here if desired. 2 Estimate starting values for the gaussian component fit 3 do the fit. 4 run ft() to put the results of the fit in the MS explicitly (as a MODEL column). 5 Extract MODEL and DATA, make the plot
fixvis(vis="J04292165_cont.ms",outputvis="J04292165_cont_recenter.ms",field="",refcode="",reuse=True,phasecenter="J2000 4h29m21.66s +27d01m25.72s",datacolumn="all")
(note: not done in this example)
do the fit -- this is for all spws together:
default uvmodelfit vis=myvis field='0' comptype='G' sourcepar=[0.006,0.1,-0.05,0.4,0.3,0.0] varypar= outfile='J04292165_cont_allspw.uv.cl' inp go
in this example we had not phase shifted.
run FT -- you must have usescratch=True
default ft vis=myvis complist='J04292165_cont_allspw.uv.cl' usescratch=True inp go # did that work? plotms(vis=myvis,xaxis='uvwave',yaxis='real',ydatacolumn='model') # yes it did.
Finally, use VISSTAT() to extract model and data values in bins of uv-radius:
import numpy as np import matplotlib.pyplot as plt import glob testms = 'J04292165_cont.ms' # set the uvrange in kilo lambda # NB: take care that the bin width and uvmin/max ranges ensure # you get no bins without data! the appropriate values may change # if you, e.g., change the SPW you are looking at uvmin = 0 #uvmax = 1200 uvmax = 800 # define steps in klambda duv=40 uvsteps = np.arange(uvmin, uvmax, duv) avg_amps =  # define an empty list in which to put the averaged amplitudes stddev_amps =  # define an empty list in which to put the amp stddev numpoints =  uvpoints = uvsteps[:-1] + np.diff(uvsteps)/2 # get array of uvmidpoints over which avg taken model_amps =  # define list to get model amplitudes after fourier transforming into the model data column # iterate over the uvrange & build up # the binned data values (looking only at the Real part -- a pretty # good approach if the signal is approximately symmetric and you have # recentered the phase center on the peak of emission): for ii in range(len(uvsteps[:-1])): tmp = visstat(vis = testms,axis = 'real', uvrange = str(uvsteps[ii]) + '~' + str(uvsteps[ii+1]) + 'klambda', datacolumn = 'data') print str(uvsteps[ii]) + '~' + str(uvsteps[ii+1]) + 'klambda' avg_amps.append(tmp['DATA']['mean']) stddev_amps.append(tmp['DATA']['stddev']) numpoints.append(tmp['DATA']['npts']) # now build up the model values for ii in range(len(uvsteps[:-1])): tmp = visstat(vis = testms, axis = 'real', # you may want to change this to real...? uvrange = str(uvsteps[ii]) + '~' + str(uvsteps[ii+1]) + 'klambda', datacolumn = 'model') print str(uvsteps[ii]) + '~' + str(uvsteps[ii+1]) + 'klambda, from the model column' model_amps.append(tmp['MODEL']['mean']) error_amps = stddev_amps/(np.sqrt(numpoints) - 1) plt.clf() plt.cla() avg_amps_mjy = [x * 1000 for x in avg_amps] model_amps_mjy = [x * 1000 for x in model_amps] error_amps_mjy = [x * 1000 for x in error_amps] plt.errorbar(uvpoints, avg_amps_mjy, yerr = error_amps_mjy, mfc='k', fmt='o', label='data') plt.plot(uvpoints, model_amps_mjy, 'r-', label=r'model from $uvmodelfit$') plt.legend(loc = 3, numpoints = 1) plt.xlabel(r'UV Distance (k$\lambda$)') plt.ylabel('Real Visibility (mJy)') plt.show()