Jupiter: continuum polarization calibration 5.5.0
DISCLAIMER |
This is an advanced reference guide to calibration and imaging of pre-upgrade VLA polarimetric data with CASA 5.3.0. If you are a beginning or novice user, please consult relevant CASA guides first. |
Data Import
The data set for this tutorial lives here (129MB). This is a VLA 6cm dataset that was observed back in 1999 to set the flux scale for calibration of the VLA. Included in the program were observations of the plants, including Jupiter which we will focus on in this tutorial. These are D-configuration data, with resolution of around 14".
Need more reliable permanent location!
Import the data into CASA. Task importuvfits() will read the original AIPS friendly UVFITS format and create a CASA native MS.
importuvfits(fitsfile='planets_6cm.fits', vis='jupiter6cm.demo.ms', antnamescheme='old')
Check the observation set up and print verbose summary of the observations to the CASA logger
listobs(vis='jupiter6cm.demo.ms')
The output of this task is fairly long, the abridged version is shown below since we may need some of this information for reference later on during our calibration.
########################################## ##### Begin Task: listobs ##### Observer: FLUX99 Project: Observation: VLA Computing scan and subscan properties... Data records: 2021424 Total elapsed time = 85136.5 seconds Observed from 15-Apr-1999/23:15:25.0 to 16-Apr-1999/22:54:21.6 (TAI) [...] Fields: 13 ID Code Name RA Decl Epoch SrcId nRows 0 A 0137+331 01:37:41.299500 +33.09.35.13400 J2000 0 72946 1 T 0813+482 08:13:36.051800 +48.13.02.26200 J2000 1 227524 2 A 0542+498 05:42:36.137900 +49.51.07.23400 J2000 2 227058 3 T 0437+296 04:37:04.174700 +29.40.15.13600 J2000 3 113424 4 VENUS 04:06:54.109428 +22.30.35.90609 J2000 4 121098 5 A 0521+166 05:21:09.886000 +16.38.22.05200 J2000 5 81258 6 T 1411+522 14:11:20.647700 +52.12.09.14100 J2000 6 243608 7 A 1331+305 13:31:08.288100 +30.30.32.96000 J2000 7 307958 8 MARS 14:21:41.365747 -12.21.49.45444 J2000 8 118570 9 NGC7027 21:07:01.593000 +42.14.10.18600 J2000 9 136082 10 NEPTUNE 20:26:01.136316 -18.54.54.21127 J2000 10 157736 11 URANUS 21:15:42.828572 -16.35.05.59272 J2000 11 99412 12 JUPITER 00:55:34.043951 +04.45.44.70633 J2000 12 114750 Spectral Windows: (2 unique spectral windows and 1 unique polarization setups) SpwID Name #Chans Frame Ch0(MHz) ChanWid(kHz) TotBW(kHz) CtrFreq(MHz) Corrs 0 none 1 TOPO 4885.100 50000.000 50000.0 4885.1000 RR RL LR LL 1 none 1 TOPO 4835.100 50000.000 50000.0 4835.1000 RR RL LR LL Sources: 26 ID Name SpwId RestFreq(MHz) SysVel(km/s) 0 0137+331 0 0 0 0 0137+331 1 0 0 1 0813+482 0 0 0 1 0813+482 1 0 0 2 0542+498 0 0 0 2 0542+498 1 0 0 3 0437+296 0 0 0 3 0437+296 1 0 0 4 VENUS 0 0 0 4 VENUS 1 0 0 5 0521+166 0 0 0 5 0521+166 1 0 0 6 1411+522 0 0 0 6 1411+522 1 0 0 7 1331+305 0 0 0 7 1331+305 1 0 0 8 MARS 0 0 0 8 MARS 1 0 0 9 NGC7027 0 0 0 9 NGC7027 1 0 0 10 NEPTUNE 0 0 0 10 NEPTUNE 1 0 0 11 URANUS 0 0 0 11 URANUS 1 0 0 12 JUPITER 0 0 0 12 JUPITER 1 0 0 Antennas 27 [....] ##### End Task: listobs ##### ##########################################
Check also the array configuration and pick a reference antenna. Here, we will use antenna '11' as a reference since it's located in the middle of the array.
plotants(vis='jupiter6cm.demo.ms', figfile='jupiter6cm.demo.ant.png')
Data Inspection and Editing
To inspect and interactively flag bad data use task plotms(). Note: it is not recommended to use plotms() to interactively flag the new post-upgrade VLA data due to their large volume and large bandwidths. However, the old VLA data are much smaller and plotms() is capable of managing it interactively.
First, inspect the primary flux and polarisation angle calibrator, 1331+305 (3C286).
plotms(vis='jupiter6cm.demo.ms', selectdata=True, field='1331+305', correlation='RR,LL', xaxis='uvdist', yaxis='amp')
Inspect RR,LL and RL,LR correlations separately due to large amplitude differences between them (when all correlations are plotted together, the RL,LR will seem like bad data due to their much lower amplitudes as compared to RR,LL). Use Mark Regions within the plotms() GUI to draw boxes around points to flag, and hit Flag to flag.
Now, inspect the other two sources we are interested in, the polarisation leakage calibrator (0137+331) and our target source (JUPITER).
The flagging can also be done non-interactively as per currently recommended CASA practise. Use task flagdata() to do so, as per example below. For example, from inspecting our data in plotms() you should have noticed that Antenna 9 (ID=8) in spw 1 is often bad. The bad data on Antenna 9 for our target source JUPITER are in the last 4 scans in spw='1' as well as in the last scan for all antennas in both spws. We can flag these points with the following flagdata() task executions.
flagdata(vis='jupiter6cm.demo.ms', mode='manual', field='JUPITER', spw='1', antenna='9', timerange='16:26:00~22:20:00')
flagdata(vis='jupiter6cm.demo.ms', mode='manual', field='JUPITER', spw='', timerange='21:40:00~22:20:00')
There are more data points to flag -- keep flagging until you are happy with the results.
If you are unfamiliar with flagging in CASA, consult detailed topical guide Flagging VLA Data.
Calibration
Set the Flux Density Scale
Set the absolute flux density scale, but only for Stokes I at the moment (total flux density model). Our primary flux calibrator here is 1331+305 (3C286). The default model for CASA 5.3+ is 'Perley-Butler 2017'.
setjy(vis='jupiter6cm.demo.ms', field='1331+305', model='3C286_C.im')
Initial gain calibration
At this stage the data have an overall flux density scaling determined, but full gain solutions aren't there yet. The relevant task is gaincal() (analogous to the AIPS task CALIB). Gaincal() will produce a separate table with solutions, and we will use appropriate extensions to keep track of what is what.
NOTE: Since we have only two single-channel continuum spw, we do not want to do bandpass calibration.
Firstly, generate an antenna zenith-angle dependent VLA gain curve calibration table
gencal(vis='jupiter6cm.demo.ms', caltable='jupiter6cm.demo.gc', caltype='gc')
Now, solve for antenna gains on 1331+305 and 0137+331, using the just generated gain curve table (.gc).
gaincal(vis='jupiter6cm.demo.ms', caltable='jupiter6cm.demo.G', field='1331+305,0137+331', spw='', gaintype='G', calmode='ap', solint='inf', combine='', refant='11', minsnr=3, gaintable=['jupiter6cm.demo.gc'], parang=False)
# And check the solutions
plotcal(caltable='jupiter6cm.demo.G', xaxis='time', yaxis='amp', subplot=333, iteration='antenna')
If all looks good, bootstrap the flux density scale of the flux calibrator onto the phase calibrators. AIPS called it GETJY, but CASA calls it fluxscale().
myFluxscale = fluxscale(vis='jupiter6cm.demo.ms', caltable='jupiter6cm.demo.G', fluxtable='jupiter6cm.demo.Gflx', reference='1331+305', transfer='0137+331', append=False, display=False)
The output is displayed in the logger as well as stored in the myFluxscale python dictionary.
Beginning fluxscale--(MSSelection version)------- Found reference field(s): 1331+305 Found transfer field(s): 0137+331 Flux density for 0137+331 in SpW=0 (freq=4.8851e+09 Hz) is: 5.29665 +/- 0.00449217 (SNR = 1179.09, N = 54) Flux density for 0137+331 in SpW=1 (freq=4.8351e+09 Hz) is: 5.34890 +/- 0.00176819 (SNR = 3025.07, N = 54) Fitted spectrum for 0137+331 with fitorder=1: Flux density = 5.32271 +/- 1.70229e-07 (freq=4.86004 GHz) spidx=-0.954124 (degenerate) Storing result in jupiter6cm.demo.Gflx Writing solutions to table: jupiter6cm.demo.Gflx
When executing fluxscale(), the calibration table with the extension .G is modified and stored as a new table with the extension .Gflx. So far, solutions have been generated only for the calibrators, and have not yet been transferred to the target source(s).
Before proceeding, inspect the flux density calibration and save results to a file.
plotcal(caltable='jupiter6cm.demo.Gflx', xaxis='time', yaxis='amp', showgui=True, figfile='jupiter6cm.demo.Gflx.amp.png')
plotcal(caltable='jupiter6cm.demo.Gflx', xaxis='time', yaxis='phase', plotrange=[-1,-1,-200,200], showgui=True, figfile='jupiter6cm.demo.Gflx.phase.png')
Polarisation calibration
Set the polarisation model
Now, set the polarisation model for the polarised position-angle calibrator (here 1331+305=3C286 which is also our primary flux calibrator). For polarisation properties of your primary polarisation calibrator see VLA Polarimetry Guide.
i0=7.3109 # Stokes I value for spw 0 ch 0
f0=4.8851 # Frequency for spw0 ch0 (note that in our data the 'lower' spw is actually higher frequency)
alpha=log(i0/7.35974932)/log(4.8351/f0) # Values from our setjy() run on Stokes I earlier
c0=0.114 # Fractional polarisation 11.4% for 5GHz
d0=33*pi/180 # Polarisation angle 33deg in radians
myPolSetjy = setjy(vis='jupiter6cm.demo.ms', field='1331+305', standard='manual', spw='0', fluxdensity=[i0,0,0,0], spix=[alpha,0], reffreq=str(f0)+'GHz', polindex=[c0,0], polangle=[d0,0], scalebychan=True, usescratch=False)
The results are displayed in the CASA logger as well as saved in the myPolSetjy python dictionary
#In CASA CASA <49>: myPolSetjy Out[49]: {'7': {'0': {'fluxd': array([ 7.3109 , 0.33899165, 0.7613877 , 0. ])}, 'fieldName': '1331+305'}, 'format': "{field Id: {spw Id: {fluxd: [I,Q,U,V] in Jy}, 'fieldName':field name }}"}
Solve for the cross-hand delays
Solve for the cross-hand delays (RL,LR) delays due to residual delay difference between R and L. For this use the 3C286 calibrator since it had a strong polarised signal in the RL and LR correlations.
gaincal(vis='jupiter6cm.demo.ms', caltable='jupiter6cm.demo.K', field='1331+305', spw='', gaintype='KCROSS', solint='inf', combine='scan', refant='11', minsnr=3, gaintable=['jupiter6cm.demo.gc','jupiter6cm.demo.G'], gainfield=['','1331+305'], parang=False)
Check the results in the CASA logger window
For solint = inf, found 2 solution intervals. Time=1999/04/16/06:38:50.8 Spw=0 Global cross-hand delay=0.102352 nsec Time=1999/04/16/06:36:31.1 Spw=1 Global cross-hand delay=0.10341 nsec Found good Kcross Jones solutions in 2 solution intervals. Writing solutions to table: jupiter6cm.demo.K Finished solving.
The cross-hand delays in our observations are very small, but if your data were associated with larger delays and you didn't correct for them, the delays would be absorbed into the phases of the D and X solutions we will solve for next. This is particularly important when solving for Q+iU polarisation.
Solve for the leakage terms (D terms)
Solve for polarization leakage on 0137+331. This step we solve for the instrumental polarization. We will assume here our calibrator has unknown polarisation (poltype='D+QU' if good parallactic coverage, 'D' otherwise, consult polcal() help for more information on options).
polcal(vis='jupiter6cm.demo.ms', caltable='jupiter6cm.demo.D', field='0137+331', spw='', refant='11', poltype='D+QU', solint='inf', combine='scan',minsnr=3, gaintable=['jupiter6cm.demo.gc', 'jupiter6cm.demo.G', 'jupiter6cm.demo.K'], gainfield=['','0137+331',''])
Check the solutions
plotcal(caltable='jupiter6cm.demo.D', xaxis='antenna', yaxis='amp', showgui=True, figfile='jupiter6cm.demo.D.amp.png')
plotcal(caltable='jupiter6cm.demo.D', xaxis='antenna', yaxis='phase', plotrange=[-1,-1,-200,200], showgui=True, figfile='jupiter6cm.demo.D.phase.png')
plotcal(caltable='jupiter6cm.demo.D', xaxis='antenna', yaxis='snr', showgui=True, figfile='jupiter6cm.demo.D.snr.png')
Solve for the R-L polarisation angle (X term)
The total polarisation is now correct (since we just calibrated the instrumental polarisation, i.e. D terms), but now the R-L phase needs to be calibrated to obtain an accurate polarisation position angle.
polcal(vis='jupiter6cm.demo.ms', caltable='jupiter6cm.demo.X', field='1331+305', spw='', refant='11', poltype='Xf', solint='inf', combine='scan',minsnr=3, gaintable=['jupiter6cm.demo.gc', 'jupiter6cm.demo.G', 'jupiter6cm.demo.K','jupiter6cm.demo.D'], gainfield=['','1331+305','',''])
Check the solutions in CASA logger window
The following calibration term is arranged for solve: . Xf Jones: table=jupiter6cm.demo.X append=false solint=inf,none refantmode='flex' refant='none' minsnr=3 apmode=AP solnorm=false For solint = inf, found 2 solution intervals. Mean position angle offset solution for 1331+305 (spw = 0) = 80.7525 deg. Mean position angle offset solution for 1331+305 (spw = 1) = -12.0478 deg. Found good Xf Jones solutions in 2 solution intervals.
something's broken here
Apply the calibration
Now that we have derived all the calibration solutions, we need to apply them to the actual data. The following tasks will apply the solution tables to the DATA and write a new column CORRECTED_DATA as it is standard for CASA. Important: make sure you set parang=True.
applycal(vis='jupiter6cm.demo.ms', field='1331+305,0137+331,JUPITER', spw='', selectdata=False, gaintable=['jupiter6cm.demo.gc', 'jupiter6cm.demo.G', 'jupiter6cm.demo.Gflx', 'jupiter6cm.demo.K','jupiter6cm.demo.D','jupiter6cm.demo.X'], calwt=[False], parang=True)
It's a good idea to split the Jupiter target data at this point. We will write the corrected data of our target source to a new single-source MS.
split(vis='jupiter6cm.demo.ms', outputvis='jupiter6cm.demo.JUPITER.split.ms', field='JUPITER', datacolumn='corrected')
You can use plotms() task to look at the split calibrated data.
Imaging (all Stokes)
We will now image and clean the calibrated Jupiter data.
tclean(vis='jupiter6cm.demo.JUPITER.split.ms', stokes='IQUV', field='', spw='', datacolumn='data', imagename='jupiter6cm.demo.JUPITER.IQUV.clean', imsize=[288], cell=['4arcsec'], specmode='mfs', gridder='standard', deconvolver='hogbom', weighting='briggs', threshold=5e-05, mask='', niter=1000, interactive=True, cycleniter=100)
Stokes I here only atm, have some problems with running tclean() today...
Inspect the quality of the cleaned images with imstat().
We now want to save each Stokes image as a separate file. We will use the immath() task to do so.
immath()
Image analysis
An example of how to display the calibrated full polarisation data. Here we will display the clean Stokes I images and overplot it with polarisation vectors. We will use the viewwer() task for this purpose.
Template:Checked 5.3.0