Ionospheric Faraday Rotation Corrections
This article details the accuracy of ionospheric Faraday rotation measure (IFRM) corrections for MeerKAT. For a full discussion, see Perley et al. 2026. The study uses MeerKAT and JVLA observations of the polarized Lunar limb to quantify the accuracy of Total Electron Content (TEC) estimations. They find that IONEX maps derived from the International GNSS Service (IGS) produced by various providers can be offset by 0.5 to 1.1 rad / m2 for the JVLA and -0.3 rad / m2 for MeerKAT. Local models derived from nearby IGS stations fare considerably better, with residuals accurate to 0.1 rad / m2 for the JVLA and 0.2 rad / m2 for MeerKAT. Observations requiring an accurate measurement of linear polarisation angle on MeerKAT should consider using TEC estimates from local GNSS stations.
Ionospheric Faraday Rotation
The Earth’s atmosphere is subjected to both solar and cosmic UV and X-ray ionisation at heights above ~100 km. Depending on solar activity, as well as source solar separation angle, daytime ionisation can result in free electron densities of up to 1012.5 m-3 at heights of ~350 km, while nighttime densities are typically an order of magnitude lower.
When coupled with the Earth’s strong dipole-driven magnetic field, this layer of free electrons causes linearly polarised light to be rotated as a function of observed wavelength squared:
Daytime ionospheric Faraday rotation ranges from -2 to -6 rad m-2, which is large enough to cause tens of degrees of rotation of the linear polarisation angle at the lower end of the L and UHF bands. Second only to HV-phase calibration, correcting for ionospheric Faraday rotation is essential to studies which require accurate measurement of the linear polarisation angle.
Global and local measurement of ionospheric TEC
The ionosphere acts as a dispersive medium, which introduces a frequency-dependent delay on radio emission propagating through it. This dispersive delay is proportional to the free electron content and can be measured for narrowly pulsed emission with sufficient frequency coverage. Dual-band modulated signals of GNSS constellations are ideal for measuring this dispersive delay introduced in the ionosphere and magnetosphere (with 60-70% of the electron content localised to the F-layer of the ionosphere during daytime).
Multiple providers in the Ionospheric Associated Analysis Centres (IAACs) of the IGS use globally distributed stations (including multiple stations situated in South Africa) to produce global maps of the ionospheric TEC. These IONEX maps are interpolated both spatially and temporally at cadences specific to the distributing provider, ranging from 2 to 0.5 hours. These maps are distributed by e.g. the Jet Propulsion Laboratory, Center for Orbit Determination in Europe and Polytechnic University of Catalonia, to name but a few.
Aside from TECOR in AIPS and the gencal task in CASA (which needs further scripting to convert IONEX maps to CASA image format), to our knowledge, two alternative programs can make use of these global IONEX maps to predict IFRM in a given line of sight. These are ionFR and RMExtract. The observatory extensively tested TECOR and RMExtract in this work.
An alternative to using global models is to create a regional model (with significantly higher time cadence) using GNSS timing data from South African TrigNET and IGS stations, using the Advanced Long Baseline User Software (ALBUS). The software has both 3-D parametric profiles of ionospheric densities and 2-D thin-shell models. The authors report getting the best IFRM residuals using the G01 thin-shell mode with the receivers at Sutherland and Pietown (for the JVLA), which have known receiver timing bias corrections.
Planetary and Lunar observations
The surface-refracted emission from rocky bodies such as the Moon is radially polarised towards the limb (see C.E. Heiles and F.D. Drake 1963) and is, to our knowledge, the only source with a priori-known polarisation angle. The IFRM introduces an offset to the radial emission, which can be used to verify the accuracy of the frequency differentially-measured IFRM using GNSS methods described above.
With MeerKAT’s resolution, the only rocky body that can be observed for this purpose is the Moon. As shown below, the fractional polarisation reaches 30% near the limb. The observatory, in conjunction with the NRAO, undertook observations of the Moon, as well as Mars and Venus on the JVLA, to characterise frequency-differential IFRM corrections. Joint observations were undertaken from VLA P-band to VLA Q-band, spanning 0.23 to 50 GHz. Lunar observations were undertaken in the period May 2017 to October 2025.
Results
The procedure used to determine the accuracy of the various IFRM corrections was to generate both uncorrected and IFRM-corrected Lunar polarisation images as a function of time and frequency, applying the different estimates of the IFRM. The images were then analysed for the mean offset from the known intrinsic radial linear polarisation angle.
Shown below are estimates from the jplg, upcg and codg global maps, as well as local ALBUS estimates from the nearby Pietown station and VLA observations of the Moon. Observations spanning night and day are the most useful in determining whether the differential change in the IFRM is removed. Evidently, all models capture this change in the IFRM, however, it is found that the global models are all offset from the observed Lunar measurements. The two observations shown are representitive for all 8 JVLA lunar P-band observations.
IFRM estimates in the direction of the Moon from three global models, a local model and direct measurement using the JVLA. The three displayed global estimates are representative of all seven providers investigated by the authors. The vertical dashed line marks sunrise or sunset. The plotted data points (in maroon, with error bars) are the actual IFRM values determined from Lunar observations.
The results of applying the various IFRM estimates to the Lunar observations are shown below as a function of wavelength squared. Here, the intercept is expected to be near zero at all wavelengths. The excellent linear fits demonstrate that the residuals of the global models are due to an overestimation of the IFRM and not due to an offset in the polarisation angle. Offsets here are due to the calibration of the dipole orientations of the receiver.
The Lunar polarisation angle measurements following correction by four IFRM estimates: the local estimate from ALBUS and three from global IONEX maps. The global estimates always significantly overestimate the correction, while the local model is always the best.
Below are the estimated and observed IFRM values for three of the MeerKAT observations, in addition to the intercepts as a function of wavelength squared. For all three, the estimates based on global IONEX maps overestimate the IFRM at all times. The single-station local ALBUS estimates are the closest to the observed values, except for the latter half of the October 30 data, which is possibly due to the large (nearly 200 km) separation from the MeerKAT site.
Global and local IFRM estimates compared to MeerKAT-observed IFRM towards the Moon.
The following figure shows the detailed before and after linear polarisation angle deviations for each 8-minute scan for two of the the 2025 observations. The plot shows the raw offsets with no corrections as solid lines and the resulting values from global (jplg model) and local ALBUS corrections as dashed lines.
The uncorrected versus corrected Lunar offsets using global and local estimates of the IFRM. 18 August 2025 on the left and 19 August 2025 to the right.
Summary
Extensive low-frequency observations of the Moon with the JVLA and MeerKAT have provided highly sensitive imaging of the Lunar polarisation properties, allowing accurate and detailed comparison of the IFRM derived from GNSS-based estimates of the ionospheric TEC. The authors compared the observed IFRM-induced variations in the linear polarisation angle from the known intrinsic radial orientation of the linear polarisation of the Lunar limb. From comparisons, they conclude the following for both MeerKAT and the JVLA:
All IFRM estimates - both global and regional - show similar changes in IFRM between day and night
All global IFRM estimates overpredict the IFRM for the JVLA observations by 0.5 to 1.1 rad / m2 and by -0.3 rad/m2 (negative sign here due to magnetic field vector inversion for the southern hemisphere) for MeerKAT, except when the IFRM values are unusually low. The offsets vary between observations, but are roughly constant for any single observation.
The local estimates provided by ALBUS are very close to the measured Lunar values, differing by typically 0.1 - 0.2 rad/m2. The G01 thin-shell mode, in combination with GNSS receivers with known DCB bias corrections, provides the most accurate IFRM estimates. For the JVLA the only station within a 300 km radius with bias corrections is the station at Pietown. For MeerKAT the ‘suthm’ station at Sutherland is well calibrated.
The overestimation in the global estimates may stem from unmodelled latitudinal gradients in the smoothened map created by using typically 200 ground stations around the globe. The remaining error in TEC estimation stems primarily from DCB bias errors. Research is underway to provide bias corrections for stations that do not have accurate bias corrections (such as those TrigNET stations not forming part of the IGS).
Example ALBUS usage
The ALBUS package is available from PyPI and is tested to work with Ubuntu 22.04. Users should install the package in a clean virtual environment. The following example script shows how to interact with the API for 3C286. Users should adjust the coordinates for their target of interest. It is noted that values obtained for a calibrator is not necessarily the same as those for a target.
#
# A basic python script that tracks a specified position on the
# sky over the time range from START_TIME to END_TIME from
# a specific location on the Earth's surface.
# The output is a text file giving Slant Tec (STEC) and
# ionosphere rotation measure (RM) as a function of time
import os
import time
import matplotlib
matplotlib.use("agg") # display should not be set
import MS_Iono_functions as iono
import math
def __run_rinex_predict(LONG, LAT, HEIGHT, OBJECT, DATA_DIR, MAX_DIST, START_TIME, END_TIME):
os.system('date')
process_start = time.time()
startime = time.strftime("%a, %d %b %Y %H:%M:%S", time.localtime())
print("getGPSIONO Start at %s" % startime)
RED_TYPE = 'RI_G01'
TIME_STEP = 300
RA = "13:31:08.28811"
DEC = "30:30:32.9600"
NUM_PROCESSORS = 1
# Note: we set NUM_PROCESSORS = 1 as we are getting data from Geosciences
# Australia, which seems to have difficulty responding to a number of ftp
# requests being received in parallel
# After the GPS data have been collected the system will increase the
# number of processors for the final ionosphere modelling
iono. process_ionosphere(time_step=TIME_STEP,
object=OBJECT,
Ra=RA,
Dec=DEC,
Lat=LAT,
Long=LONG,
Height=HEIGHT,
start_time=START_TIME,
end_time=END_TIME,
max_dist=MAX_DIST,
processing_option=RED_TYPE,
do_serial=0,
num_processors=NUM_PROCESSORS,
gps_data_directory=DATA_DIR)
os.system('date')
endtime = time.strftime("%a, %d %b %Y %H:%M:%S", time.localtime())
print("getGPSIONO End at %s" % endtime)
print (' ')
process_end = time.time()
duration = (process_end - process_start)/60.0
print("getGPSIONO Total run time: %7.2f minutes" % duration)
def __checkmake_outputdir():
testoutdir = os.environ.get("ALBUS_TESTCASE_OUTPUT", "/albus_waterhole")
if os.path.exists(testoutdir):
outputhiddendir = os.path.join(testoutdir, 'datadumps')
if not os.path.exists(outputhiddendir):
os.mkdir(outputhiddendir)
else:
raise RuntimeError("'%s' must be a valid directory -- are you running inside Docker, check mount path?" % testoutdir)
return outputhiddendir
if __name__ == "__main__":
# MEERKAT telescope location
# mean of MeerKAT_Cartesian_coordinate.csv coordinates
# this can be adjusted to Sutherland to use the bias-corrected stations
LONG="21:26:35.736"
LAT="-30:42:44.838"
HEIGHT=1059.662443
MAX_DIST=350E3 # km
# UHF
START_TIME="2021/06/22 17:02:00.7"
END_TIME="2021/06/22 20:18:00.2"
OBJECT="MeerKat_Moon_Jun_22_UHF_3C286"
DATA_DIR = os.path.join(__checkmake_outputdir(), 'MeerKat_3C286_test_3C286_Jun_22_UHF')
__run_rinex_predict(LONG, LAT, HEIGHT, OBJECT, DATA_DIR, MAX_DIST, START_TIME, END_TIME)An example of a report produced by ALBUS is shown below. Estimates of the slant TEC as well as RM are given
Observing MeerKat_Moon_Jun_22_UHF_3C286
ALBUS data processing option: RI_G01
station position [[ 5109286.83908611 2006759.06551835 -3239067.78122689]]
Potential number of receivers for GPS fit 1
Final number of receivers for GPS fit 1
set ground station position to 5109286.83909 2006759.06552 -3239067.78123
reference time for rel_time=0: year,month,day,hr,min,sec 2021 6 22 17 2 1.0
Measurement set actual integration centroid start and end times 5131098120.7 5131109880.2
observation direction 13:31:08.28811 30:30:32.9600
ALBUS report column explanation (zero relative):
0 - sequence number (zero relative)
1 - separator colon
2 - value of 0 - valid data/calculation
value of 1 - invalid data/calculation (usually, but not always, because elevation < 0 )
3 - relative time in seconds relative to reference time
4 - time step between sequence calculations (default is 300 sec)
5 - elevation in degrees
6 - azimuth in degrees
7 - TEC (in tec units) in the current azimuth/elevation direction
8 - Rotation Measure (radians/m^2) in the current azimuth/elevation direction
9 - correction factor to convert STEC to value at the zenith
10 - formal error in STEC
seq rel_time time_width El Az STEC RM (rad/m2) VTEC factor STEC_error
0 : 0 -300.0 300.0 26.9684378595 15.701915888 10.4063562823 -0.540450131868 0.524581488113 0.215944139733
1 : 0 0.0 300.0 27.2494538587 14.5291505364 10.2413716533 -0.535467775332 0.528030640979 0.214485592993
2 : 0 300.0 300.0 27.5090347922 13.3472993447 10.2219904109 -0.537858932585 0.531218132053 0.189312523292
3 : 0 600.0 300.0 27.7469100342 12.1569817247 10.0595636285 -0.532486419731 0.534140046865 0.188248050705
4 : 0 900.0 300.0 27.962827622 10.9588510744 9.9115601253 -0.527601657975 0.536792852911 0.187375840562
5 : 0 1200.0 300.0 28.1565555072 9.75359288112 9.31514329999 -0.498455359705 0.539173387947 0.209846392766
6 : 0 1500.0 300.0 28.3278827299 8.5419225532 8.54464757989 -0.459452946966 0.541278849664 0.186038167405
7 : 0 1800.0 300.0 28.4766205175 7.32458291377 8.47561833928 -0.457789441597 0.543106786814 0.185371986008
8 : 0 2100.0 300.0 28.6026032826 6.10234145455 8.40297104631 -0.455734517675 0.544655091537 0.184772033495
9 : 0 2400.0 300.0 28.7056895179 4.87598729003 8.35358149133 -0.454750861502 0.545921992923 0.184248739889
10 : 0 2700.0 300.0 28.7857625693 3.64632792042 8.27600949875 -0.45204387281 0.546906051645 0.183967495732
11 : 0 3000.0 300.0 28.8427312843 2.41418575535 8.18792491313 -0.448569001821 0.54760615569 0.183859203115
12 : 0 3300.0 300.0 28.8765305215 1.18039449783 8.15321814365 -0.447834236116 0.548021517063 0.183759606691
13 : 0 3600.0 300.0 28.8871215183 -0.0542045983423 8.09910822558 -0.445856711619 0.548151669484 0.184304114485
14 : 0 3900.0 300.0 28.8744921108 -1.28876658241 8.09026247125 -0.446198084545 0.547996467034 0.183973378144
15 : 0 4200.0 300.0 28.838656803 -2.52244666378 8.04169333875 -0.44417770414 0.547556083728 0.206910302267
16 : 0 4500.0 300.0 28.7796566842 -3.75440410858 8.04443330038 -0.444821850601 0.546831014018 0.207070425112
17 : 0 4800.0 300.0 28.6975591966 -4.9838060489 7.43306269221 -0.411317518595 0.545822074243 0.185937783104
18 : 0 5100.0 300.0 28.5924577537 -6.20983124436 6.57794452163 -0.36412946027 0.544530405005 0.207868961927
19 : 0 5400.0 300.0 28.4644712194 -7.43167367219 7.17330819565 -0.397080775405 0.542957474555 0.186002148379
20 : 0 5700.0 300.0 28.3137432482 -8.64854598732 7.09156111624 -0.39240331679 0.541105083156 0.187037110203
21 : 0 6000.0 300.0 28.1404414994 -9.85968275293 7.05062424425 -0.389841144262 0.538975368532 0.168387136556
22 : 0 6300.0 300.0 27.9447567364 -11.0643434366 6.26151040364 -0.345817125348 0.53657081244 0.18728387353
23 : 0 6600.0 300.0 27.7269018141 -12.2618151708 6.00076873129 -0.330917523226 0.533894248397 0.187719654501
24 : 0 6900.0 300.0 27.4871105793 -13.4514151931 6.01649352998 -0.331161808551 0.530948870742 0.188828683971
25 : 0 7200.0 300.0 27.2256366819 -14.6324930277 6.02901094818 -0.33110480628 0.527738244994 0.189856951683
26 : 0 7500.0 300.0 26.9427523265 -15.8044323179 6.01794237277 -0.329631792032 0.524266319794 0.191055370052
27 : 0 7800.0 300.0 26.6387469606 -16.9666523823 6.03497271788 -0.329577428851 0.520537440348 0.192162384224
28 : 0 8100.0 300.0 26.3139259311 -18.1186094159 5.83090720914 -0.317365175108 0.516556363756 0.217492305137
29 : 0 8400.0 300.0 25.9686091037 -19.2597974148 5.85763358092 -0.317633872349 0.512328276148 0.219220910798
30 : 0 8700.0 300.0 25.6031294741 -20.3897487727 5.79713753184 -0.313069567144 0.507858812002 0.221086617306
31 : 0 9000.0 300.0 25.2178317764 -21.5080345853 5.95519868081 -0.320175539867 0.503154075791 0.198534738088
32 : 0 9300.0 300.0 24.8130710935 -22.6142647009 5.95577217095 -0.318667389243 0.498220666067 0.200420661715
33 : 0 9600.0 300.0 24.3892114976 -23.7080874771 5.96638259051 -0.317586839757 0.493065702473 0.202542351039
34 : 0 9900.0 300.0 23.9466247069 -24.7891893348 6.12638574945 -0.324304684207 0.487696855661 0.184472559725
35 : 0 10200.0 300.0 23.4856887936 -25.8572940591 6.1179835886 -0.321960065726 0.482122380714 0.186550706316
36 : 0 10500.0 300.0 23.006786922 -26.9121619415 6.0984963139 -0.31894120899 0.476351154062 0.188833803049
37 : 0 10800.0 300.0 22.5103061527 -27.9535887151 6.09223795211 -0.316526915623 0.470392714567 0.191144245536
38 : 0 11100.0 300.0 21.9966362889 -28.9814043751 6.13851292884 -0.316736018543 0.464257308765 0.193654173682
39 : 0 11400.0 300.0 21.4661687923 -29.9954718535 6.1920481769 -0.31719548509 0.457955940909 0.196363054775
40 : 0 11700.0 300.0 20.9192957638 -30.9956855906 6.17321962311 -0.313851785757 0.451500428044 0.199046365116
41 : 0 12000.0 300.0 20.3564089781 -31.9819700487 6.13625664544 -0.309530177988 0.444903460291 0.20200407889
process_ionosphere: total run time: 2.52 minutes