15–19 Sept 2025
JIVE
Europe/Amsterdam timezone

Data reduction guide

VLBI Data Reduction and Imaging Tutorial

Advanced Tutorial 3: Introduction to VLBI data reduction and imaging

Originally developed for the 10th European Radio Interferometry School in Granada (IAA-CSIC, September 30 – October 4, 2024)


Overview

This is a hands-on introduction to VLBI data reduction using CASA. The tutorial dataset will be updated with data from the e-EVN observation conducted during the school.

Note: This is a simplified introduction. For more detailed guides, please refer to:

 


Data Download

Download the tutorial dataset (320 MB):

 


Dataset Information

Observation: N23C2 continuum dataset 

Type: EVN network monitoring test with phase-referencing 

Duration: ~2 hours 

Method: Telescopes nodding between calibrator (C) and target (T) in C-T-C-T pattern

Source Type Source Name
Calibrator (C) J0854+2006
Target (T) J0905+2052

Data Reduction in CASA

Setup

Navigate to your working directory and start CASA:

 
bash
cd ~/ERIS/n23c2-eris-vlbi/
casa

Step 1: Loading and Inspecting Data

Load the data:

default(importfitsidi)
fitsidifile='n23c2_1_1.IDI'
vis='n23c2.ms'
constobsid=True
scanreindexgap_s=15
importfitsidi()

 

Load flag table: Download the flag file: n23c2.flag

default(flagdata)
vis='n23c2.ms'
mode='list'
inpfile='n23c2.flag'
flagdata()

 

Understand your data:

default(listobs)
vis='n23c2.ms'
listfile='n23c2.ms.listobs'
overwrite=True
listobs()

 

Inspect uncalibrated data:

default(plotms)
vis='n23c2.ms'
xaxis='frequency'
yaxis='amp'
field='J0854+2006'
avgtime='3600'
antenna='EF&*'
gridrows=3
gridcols=3
iteraxis='antenna'
coloraxis='scan'
plotms()

 

Step 2: A Priori Amplitude Calibration

Generate system temperature information:

default(gencal)
vis='n23c2.ms'
caltable='n23c2.tsys'
caltype='tsys'
uniform=False
gencal()

 

Generate gain curves:

default(gencal)
vis="n23c2.ms"
caltable= "n23c2.gcal"
caltype="gc"
gencal()

 

Inspect Tsys corrections:

default(plotms)
vis='n23c2.tsys'
xaxis='frequency'
yaxis='tsys'
gridrows=3
gridcols=3
coloraxis='corr'
iteraxis='antenna'
plotms()
xaxis='time'
plotms()

 

Step 3: Data Inspection and Flagging

Plot amplitude vs frequency on sensitive baseline:

default(plotms)
vis='n23c2.ms'
xaxis='channel'
yaxis='amp'
field='J0854+2006'
avgtime='3600'
antenna='EF&JB'
iteraxis='spw'
gridrows=1
gridcols=4
plotms()

 

Flag band edges:

default(flagdata)
vis='n23c2.ms'
mode='manual'
spw='*:0~3;60~63'
flagdata()

 

Flag autocorrelations:

default(flagdata)
vis='n23c2.ms'
mode='manual'
autocorr=True
flagdata()

 

Step 4: Fringe Fitting

Identify good timerange and check data:

 
default(plotms)
vis='n23c2.ms'
xaxis='frequency'
yaxis='phase'
ydatacolumn='data'
antenna='EF&*'
coloraxis='corr'
timerange='14:32:00~14:33:00'
averagedata=True
avgtime='120'
iteraxis='antenna'
gridrows=3
gridcols=3
plotms()

 

Calculate delays (SBD - Single Band Delays):

default(fringefit)
vis='n23c2.ms'
caltable='n23c2.sbd'
timerange='14:32:00~14:33:00'
solint='inf'
zerorates=True
refant='EF'
minsnr=10
gaintable=['n23c2.gcal','n23c2.tsys']
interp=['nearest','nearest,nearest']
parang=True
fringefit()

 

Apply SBD solutions:

default(applycal)
vis='n23c2.ms'
gaintable=['n23c2.gcal','n23c2.tsys','n23c2.sbd']
interp=['nearest','nearest,nearest','nearest']
parang=True
applycal()

 

Check corrected data:

tget(plotms)
ydatacolumn='corrected'
plotms()

 

Multi-band delays and rates (MBD):

default(fringefit)
vis='n23c2.ms'
caltable='n23c2.mbd'
field='J0854+2006'
solint='120s'
zerorates=False
refant='EF'
combine='spw'
minsnr=7
gaintable=['n23c2.gcal','n23c2.tsys','n23c2.sbd']
interp=['nearest','nearest,nearest','nearest']
parang=True
fringefit()

 

Inspect MBD solutions:

default(plotms)
vis='n23c2.mbd'
xaxis='time'
yaxis='delay'
gridrows=4
gridcols=4
coloraxis='corr'
iteraxis='antenna'
plotms()

 

Apply phase referencing:

default(applycal)
vis='n23c2.ms'
field='J0854+2006,J0905+2052'
gaintable=['n23c2.gcal','n23c2.tsys','n23c2.sbd','n23c2.mbd']
interp=['nearest', 'nearest,nearest','nearest','linear']
spwmap=[[],[],[],[0,0,0,0]]
parang=True
applycal()

 

Step 5: Bandpass Calibration

Calculate bandpass:

 
default(bandpass)
vis='n23c2.ms'
caltable='n23c2.bpass'
field='J0854+2006'
gaintable=['n23c2.gcal','n23c2.tsys','n23c2.sbd','n23c2.mbd']
interp=['nearest','nearest,nearest','nearest','linear']
solnorm=True
solint='inf'
refant='EF'
bandtype='B'
spwmap=[[],[],[],[0,0,0,0]]
parang=True
bandpass()

 

Inspect bandpass solutions:

default(plotms)
vis='n23c2.bpass'
xaxis='frequency'
yaxis='amp'
coloraxis='corr'
iteraxis='antenna'
plotms()

 

Apply all calibrations:

default(applycal)
vis='n23c2.ms'
field='J0854+2006,J0905+2052'
gaintable=['n23c2.gcal','n23c2.tsys','n23c2.sbd','n23c2.mbd','n23c2.bpass']
interp=['nearest','nearest,nearest','nearest','linear','nearest,nearest']
spwmap=[[],[],[],[0,0,0,0],[]]
parang=True
applycal()

 

Step 6: Export Data

Create calibrated datasets:

# Calibrator
default(mstransform)
vis='n23c2.ms'
outputvis='n23c2_J0854+2006.ms'
field='J0854+2006'
datacolumn='corrected'
keepflags=True
chanaverage=True
chanbin=64
mstransform()

# Target
default(mstransform)
vis='n23c2.ms'
outputvis='n23c2_J0905+2052.ms'
field='J0905+2052'
datacolumn='corrected'
keepflags=True
chanaverage=True
chanbin=64
mstransform()

 

Export to UV FITS:

# Calibrator
default(exportuvfits)
vis='n23c2_J0854+2006.ms'
fitsfile='n23c2_J0854+2006.uvfits'
combinespw=True
padwithflags=True
datacolumn='corrected'
exportuvfits()

# Target
default(exportuvfits)
vis='n23c2_J0905+2052.ms'
fitsfile='n23c2_J0905+2052.uvfits'
combinespw=True
padwithflags=True
datacolumn='corrected'
exportuvfits()