Flux and bandpass calibration
MeerKAT makes use of J1939-6342 (PKS B1934-638) and J0408-6545 (PKS B0407-65) as the flux and bandpass calibrators. Due to MeerKAT’s wide field of view and sensitivity, there is structure introduced into the bandpass response from secondary sources in the field. It is necessary to use a multi-component model for the primary calibrators to derive a stable bandpass calibration and an accurate flux scale. This is vital at the UHF band, as shown below, but it is also advisable to do so at L-band for accurate bandpass calibration. Point source models are most reliable at the S-band, as the impact of off-axis field sources is significantly limited by the smaller antenna far-field beam.
The L-, UHF and S-band calibrator models used by the SDP pipeline, in wsclean format, can be found here.
J1939-6342
J1939-6342 (Figure 1) has an additional ~20% flux contribution from other sources in the field at 900 MHz, and up to 40% at 600 MHz with its spectrum turning over at ~1 GHz. These sources cause time-variable ripples across the bandpass in both phase and amplitude (examples shown in Figure 2). While the standard CASA flux density models can be used for L-band data reduction, it is essential to use multi-component models for UHF observations.
A full discussion of the observations and models are included in this commissioning report. The SDP calibrator pipeline is currently using 90 components. This is sufficient for most cases.
J0408-6545
This source has somewhat lower interference from other sources in the field (1% contribution at L-band); there is a bright double-lobed source at the 1% (integrated flux) level 5.5 arcmin away from the central source.
Using CASA setjy for non-standard flux models
There isn’t a standard flux model available for J0408-6545 in CASA. The code below shows how to set the model (using only the primary source in the field).
def casa_flux_model(lnunu0, iref, *args):
"""
Compute model:
iref * 10**lnunu0 ** (args[0] + args[1] * lnunu0 + args[1] * lnunu0 ** 2 + args[0] * lnunu0 ** 3)
"""
exponent = np.sum([arg * (lnunu0 ** (power ))
for power, arg in enumerate(args)], axis=0)
return iref * (10**lnunu0) **(exponent)
def fit_flux_model(nu, s, nu0, sigma, sref, order=5):
from scipy.optimize import curve_fit
from scipy.special import binom
"""
Fit a flux model of given order from :
S = fluxdensity *(freq/reffreq)**(spix[0]+spix[1]*log(freq/reffreq)+..)
Very rarely, the requested fit fails, in which case fall
back to a lower order, iterating until zeroth order. If all
else fails return the weighted mean of the components.
Finally convert the fitted parameters to a
katpoint FluxDensityModel:
log10(S) = a + b*log10(nu) + c*log10(nu)**2 + ...
Parameters
----------
nu : np.ndarray
Frequencies to fit in Hz
s : np.ndarray
Flux densities to fit in Jy
nu0 : float
Reference frequency in Hz
sigma : np.ndarray
Errors of s
sref : float
Initial guess for the value of s at nu0
order : int (optional)
The desired order of the fitted flux model (1: SI, 2: SI + Curvature ...)
"""
init = [sref, -0.7] + [0] * (order - 1)
lnunu0 = np.log10(nu/nu0)
for fitorder in range(order, -1, -1):
try:
popt, _ = curve_fit(casa_flux_model, lnunu0, s, p0=init[:fitorder + 1], sigma=sigma)
except RuntimeError:
log.warn("Fitting flux model of order %d to CC failed. Trying lower order fit." %
(fitorder,))
else:
coeffs = np.pad(popt, ((0, order - fitorder),), "constant")
return [nu0] + coeffs.tolist()
# Give up and return the weighted mean
coeffs = [np.average(s, weights=1./(sigma**2))] + [0] * order
return [nu0]+ coeffs.tolist()
def convert_flux_model(nu=np.linspace(0.9,2,200)*1e9 , a=1,b=0,c=0,d=0,Reffreq= 1.0e9) :
"""
Convert a flux model from the form:
log10(S) = a + b*log10(nu) + c*log10(nu)**2 + ...
to an ASA style flux model in the form:
S = fluxdensity *(freq/reffreq)**(spix[0]+spix[1]*log(freq/reffreq)+..)
Parameters
----------
nu : np.ndarray
Frequencies to fit in Hz
a,b,c,d : float
parameters of a log flux model.
Reffreq : float
Reference frequency in Hz
returns :
reffreq,fluxdensity,spix[0],spix[1],spix[2]
"""
MHz = 1e6
S = 10**(a + b*np.log10(nu/MHz) +c*np.log10(nu/MHz)**2 + d*np.log10(nu/MHz)**3)
return fit_flux_model(nu, S , Reffreq,np.ones_like(nu),sref=1 ,order=3)
#name=0408-65 epoch=2016 ra=04h08m20.4s dec=-65d45m09s a=-0.9790 b=3.3662 c=-1.1216
a=-0.9790
b=3.3662
c=-1.1216
d=0.0861
reffreq,fluxdensity,spix0,spix1,spix2 = convert_flux_model(np.linspace(0.9,2,200)*1e9,a,b,c,d)
f_cal_alt = 'J0408-6545'
setjy(vis=msfile,
field=f_cal_alt,
spix=[spix0, spix1, spix2, 0],
fluxdensity = fluxdensity,
reffreq='%f Hz'%(reffreq),
standard='manual')
Applying a full sky model to a CASA measurement set
The calibrator models can be found here and here, and are in wsclean format.
The crystalball package can be used to populate the ‘MODEL_DATA' column of a measurement set. This replaces CASA’s own setjy task as crystalball utilises all the components in the sky model. setjy by default assumes a single point source model at the phase center of the flux calibrator field. A model image may also be provided for use with setjy.
crystalball can be used as follows:
$ crystalball observation.ms -sm skymodel.txt -f 0for the measurement set “observation.ms”, sky model “skymodel.txt” and flux calibrator field ID “0”.
Calibration can proceed as normal after this step.
Please note that 3C 286 (J1331+3030), which is mainly used as a polarisation calibrator owing to its multi-decade stability, can also be used as MeerKAT flux calibrator in L-band. However, using the same calibrator for bandpass, flux, and polarisation calibration in a single observing block is not recommended, as each calibration type has distinct requirements:
Bandpass and Flux Calibration: Requires a strong, unpolarised, and stable source with a well-known flux, but does not require a detailed polarisation model.
Polarisation Calibration: Requires a calibrator with a well-known and stable polarisation angle and fraction, and—critically—a full and accurate polarisation model across the observing band.
Using the same source can introduce systematic errors, as instrumental effects and calibration errors may contaminate all solutions, especially if the calibrator lacks a suitable polarisation model. Best practice is to use separate, well-characterised calibrators for each purpose to ensure accurate and reliable calibration. For more details, see Polarisation Calibration.
S-band flux and bandpass calibration
J1939-6342 and J0408-6545 remain the recommended flux and bandpass calibrators at S-band. However, several important differences from L-band and UHF apply.
The point source model is sufficient
Unlike at UHF and L-band, a point source model is adequate for J1939-6342 at S-band frequencies. The impact of off-axis field source fluxes is limited by the smaller antenna far-field beam at these higher frequencies, significantly reducing the structure introduced into the bandpass response from secondary sources in the field. This has been confirmed by both Hugo (2022) and Ranchod et al. (2024). Therefore, the standard CASA setjy flux density models can be used directly for S-band data reduction — the multi-component crystalball approach described above for UHF (and recommended for L-band) is not strictly necessary, though it remains harmless to apply.
For J0408-6545, the setjy code shown above in the J0408-6545 section can be used at S-band frequencies by adjusting the frequency range in the convert_flux_model call to span the relevant S-band sub-band (e.g. np.linspace(1.75, 3.5, 200)*1e9). The Partridge et al. (2016) model coefficients remain valid across this range.
Bandpass stability
Bandpass solutions at S-band have been shown to remain fairly stable over the course of an observation, consistent with the behaviour at L-band. ThunderKAT S3 commissioning observations confirmed that antenna-based bandpass amplitude gains were stable, with smooth phase profiles across the band (ThunderKAT 2023 report). The standard recommended cadence (10 minutes on the bandpass/flux calibrator every 3 hours) also applies to S-band. See Calibration strategies for the full observing strategy.
Flux scale accuracy
The Reynolds (1994)/Partridge et al. (2016) flux scales agree with the Perley-Butler (2017) scale to within ~2% across most of the S-band range (Hugo, 2022). However, users should be aware of the following caveats:
Pointing-related gain variability is more pronounced at S-band than at L-band due to the smaller beam size (mean blind pointing ~40″ at night, ~50″ during the day). This can introduce significant gain scatter, particularly in the S3 and S4 sub-bands, leading to average flux errors of ~5% at the highest frequencies in affected observations.
Inter-observation gain variations have been noted in S3 and S4, likely caused by residual pointing errors. Users should inspect SDP calibration reports (or their own gain solutions) for high scatter before selecting a reference antenna.
Weather sensitivity is increased at S-band. Gain instability has been observed to coincide with rainstorms. See the S-band capability and status page for further details.
Self-calibration recommendation
Reference calibration alone may not be sufficient at S-band due to small-scale gain fluctuations on some baselines. At least one round of phase self-calibration is strongly recommended for continuum imaging. ThunderKAT commissioning observations demonstrated that self-calibration improved image artefacts by ~20% relative to reference calibration alone (ThunderKAT 2023 report). For high dynamic range imaging, direction-dependent calibration (peeling) is recommended and has been shown to greatly reduce artefacts, consistent with antenna pointing errors being the dominant cause at S-band frequencies (Cotton, 2021). See also the Dynamic range considerations page.
RFI impact on bandpass
Globalstar satellite RFI at 2483.5–2495.0 MHz affects the S3 sub-band, primarily on short baselines. Baseline-dependent flagging is recommended. Overall, S3 observations show approximately 10% data loss due to flagging (ThunderKAT 2023 report). See the RFI page for further details. Users working in the S3 sub-band should account for this flagging overhead when planning integration time.