diff --git a/README.md b/README.md
index da4288bc3768195c6155a68468a32d0dd38828e2..d1ec2f348ec4831d29f25fc1d61b79370e2f69c6 100644
--- a/README.md
+++ b/README.md
@@ -115,6 +115,7 @@ Next change the version in the following places:
 
 # Release Notes
 
+* 0.4.1 Fix for missing SDP attributes for spectral inversion
 * 0.4.0 Have most containers report health status and add `make await` command
 * 0.3.1 Fix for applying boot device dsconfig
 * 0.3.0 Initial version of deployment scripts and functionality
diff --git a/tangostationcontrol/VERSION b/tangostationcontrol/VERSION
index 1d0ba9ea182b0f7354f3daf12120744ec5e0c2f8..267577d47e497a0630bc454b3f74c4fd9a10ced4 100644
--- a/tangostationcontrol/VERSION
+++ b/tangostationcontrol/VERSION
@@ -1 +1 @@
-0.4.0
+0.4.1
diff --git a/tangostationcontrol/tangostationcontrol/devices/antennafield.py b/tangostationcontrol/tangostationcontrol/devices/antennafield.py
index 0363b5af38f6706a4a3334ed12b2a50eebbea1b0..2c89283f88c123042c1b8bc531b1623b374d62c8 100644
--- a/tangostationcontrol/tangostationcontrol/devices/antennafield.py
+++ b/tangostationcontrol/tangostationcontrol/devices/antennafield.py
@@ -152,25 +152,25 @@ class AntennaField(lofar_device):
     )
 
     Calibration_SDP_Subband_Weights_50MHz = device_property(
-        doc=f"Measured calibration values for the sdp.FPGA_subband_weights_RW columns of each antenna, at 50 MHz. Each antenna is represented by a (real, imag) pair for every subband.",
+        doc=f"Measured calibration values for the sdp.FPGA_subband_weights_RW columns of each polarisation of each antenna, at 50 MHz. Each polarisation is represented by a (real, imag) pair for every subband.",
         dtype='DevVarFloatArray',
         mandatory=False
     )
 
     Calibration_SDP_Subband_Weights_150MHz = device_property(
-        doc=f"Measured calibration values for the sdp.FPGA_subband_weights_RW columns of each antenna, at 150 MHz. Each antenna is represented by a (real, imag) pair for every subband.",
+        doc=f"Measured calibration values for the sdp.FPGA_subband_weights_RW columns of each polarisation of each antenna, at 150 MHz. Each polarisation is represented by a (real, imag) pair for every subband.",
         dtype='DevVarFloatArray',
         mandatory=False
     )
 
     Calibration_SDP_Subband_Weights_200MHz = device_property(
-        doc=f"Measured calibration values for the sdp.FPGA_subband_weights_RW columns of each antenna, at 200 MHz. Each antenna is represented by a (real, imag) pair for every subband.",
+        doc=f"Measured calibration values for the sdp.FPGA_subband_weights_RW columns of each polarisation of each antenna, at 200 MHz. Each polarisation is represented by a (real, imag) pair for every subband.",
         dtype='DevVarFloatArray',
         mandatory=False
     )
 
     Calibration_SDP_Subband_Weights_250MHz = device_property(
-        doc=f"Measured calibration values for the sdp.FPGA_subband_weights_RW columns of each antenna, at 250 MHz. Each antenna is represented by a (real, imag) pair for every subband.",
+        doc=f"Measured calibration values for the sdp.FPGA_subband_weights_RW columns of each polarisation of each antenna, at 250 MHz. Each polarisation is represented by a (real, imag) pair for every subband.",
         dtype='DevVarFloatArray',
         mandatory=False
     )
@@ -303,13 +303,13 @@ class AntennaField(lofar_device):
         dtype=(numpy.uint32,), max_dim_x=MAX_ANTENNA, unit="dB")
     Calibration_SDP_Fine_Calibration_Default_R = attribute(
         doc=f"Computed calibration values for the fine calibration of each antenna. Each antenna is represented by a (delay, phase_offset, amplitude_scaling) triplet.",
-        dtype=((numpy.float64,),), max_dim_y=MAX_ANTENNA, max_dim_x=3)
+        dtype=((numpy.float64,),), max_dim_y=MAX_ANTENNA * N_pol, max_dim_x=3)
     Calibration_SDP_Subband_Weights_Default_R = attribute(
-        doc=f"Calibration values for the rows in sdp.FPGA_subband_weights_RW relevant for our antennas, as computed. Each subband of each antenna is represented by a real_imag number (real, imag).",
-        dtype=((numpy.float64,),), max_dim_y=MAX_ANTENNA, max_dim_x=N_subbands * VALUES_PER_COMPLEX)
+        doc=f"Calibration values for the rows in sdp.FPGA_subband_weights_RW relevant for our antennas, as computed. Each subband of each polarisation of each antenna is represented by a real_imag number (real, imag).",
+        dtype=((numpy.float64,),), max_dim_y=MAX_ANTENNA * N_pol, max_dim_x=N_subbands * VALUES_PER_COMPLEX)
     Calibration_SDP_Subband_Weights_R = attribute(
-        doc=f"Calibration values for the rows in sdp.FPGA_subband_weights_RW relevant for our antennas. Each subband of each antenna is represented by a real_imag number (real, imag). Returns the measured values from Calibration_SDP_Subband_Weights_XXXMHz if available, and values computed from Calibration_SDP_Fine_Calibration_Default_R otherwise.",
-        dtype=((numpy.float64,),), max_dim_y=MAX_ANTENNA, max_dim_x=N_subbands * VALUES_PER_COMPLEX)
+        doc=f"Calibration values for the rows in sdp.FPGA_subband_weights_RW relevant for our antennas. Each subband of each polarisation of each antenna is represented by a real_imag number (real, imag). Returns the measured values from Calibration_SDP_Subband_Weights_XXXMHz if available, and values computed from Calibration_SDP_Fine_Calibration_Default_R otherwise.",
+        dtype=((numpy.float64,),), max_dim_y=MAX_ANTENNA * N_pol, max_dim_x=N_subbands * VALUES_PER_COMPLEX)
 
     # ----- Quality and usage information
 
@@ -426,10 +426,14 @@ class AntennaField(lofar_device):
         return input_delay_samples
 
     def read_Calibration_SDP_Fine_Calibration_Default_R(self):
+        def repeat_per_pol(arr):
+            # repeat values twice, and restore the shape (with the inner dimension being twice the size now)
+            return numpy.dstack((arr,arr)).reshape(arr.shape[0] * N_pol, *arr.shape[1:])
+
         # ----- Delay
 
-        # correct for signal delays in the cables
-        signal_delay_seconds = self.read_attribute("Antenna_Cables_Delay_R")
+        # correct for signal delays in the cables (equal for both polarisations)
+        signal_delay_seconds = repeat_per_pol(self.read_attribute("Antenna_Cables_Delay_R"))
 
         # compute the required compensation
         clock = self.sdp_proxy.clock_RW
@@ -438,17 +442,17 @@ class AntennaField(lofar_device):
         # ----- Phase offsets
 
         # we don't have any
-        phase_offsets = numpy.zeros((self.read_attribute("nr_antennas_R"),),dtype=numpy.float64)
+        phase_offsets = repeat_per_pol(numpy.zeros((self.read_attribute("nr_antennas_R"),),dtype=numpy.float64))
 
         # ----- Amplitude
 
         # correct for signal loss in the cables
-        signal_delay_loss = self.read_attribute("Antenna_Cables_Loss_R") - self.Field_Attenuation
+        signal_delay_loss = repeat_per_pol(self.read_attribute("Antenna_Cables_Loss_R") - self.Field_Attenuation)
 
         # return fine scaling to apply
         _, input_attenuation_remaining_factor = loss_compensation(signal_delay_loss)
 
-        # Return as (delay, phase_offset, amplitude) triplet per antenna
+        # Return as (delay, phase_offset, amplitude) triplet per polarisation
         return numpy.stack((input_delay_subsample_seconds, phase_offsets, input_attenuation_remaining_factor), axis=1)
 
     def read_Calibration_SDP_Subband_Weights_Default_R(self):
@@ -459,8 +463,7 @@ class AntennaField(lofar_device):
         nr_antennas = self.read_attribute("nr_antennas_R")
         antenna_to_sdp_mapping = self.read_attribute("Antenna_to_SDP_Mapping_R")
 
-
-        subband_weights = numpy.zeros((nr_antennas, N_subbands, VALUES_PER_COMPLEX), dtype=numpy.float64)
+        subband_weights = numpy.zeros((nr_antennas, N_pol, N_subbands, VALUES_PER_COMPLEX), dtype=numpy.float64)
 
         # compute real_imag weight for each subband
         for antenna_nr in range(nr_antennas):
@@ -468,20 +471,21 @@ class AntennaField(lofar_device):
             if input_nr == -1:
                 continue
 
-            delay, phase_offset, amplitude = delay_phase_amplitude[antenna_nr, :]
+            for pol_nr in range(N_pol):
+                delay, phase_offset, amplitude = delay_phase_amplitude[antenna_nr * N_pol + pol_nr, :]
 
-            for subband_nr in range(N_subbands):
-                frequency = subband_frequency(subband_nr, clock, nyquist_zone[fpga_nr, input_nr])
+                for subband_nr in range(N_subbands):
+                    frequency = subband_frequency(subband_nr, clock, nyquist_zone[fpga_nr, input_nr])
 
-                # turn signal backwards to compensate for the provided delay and offset
-                phase_shift = -(2 * numpy.pi * frequency * delay + phase_offset)
+                    # turn signal backwards to compensate for the provided delay and offset
+                    phase_shift = -(2 * numpy.pi * frequency * delay + phase_offset)
 
-                real = numpy.cos(phase_shift) * amplitude
-                imag = numpy.sin(phase_shift) * amplitude
+                    real = numpy.cos(phase_shift) * amplitude
+                    imag = numpy.sin(phase_shift) * amplitude
 
-                subband_weights[antenna_nr, subband_nr, :] = (real, imag)
+                    subband_weights[antenna_nr, pol_nr, subband_nr, :] = (real, imag)
 
-        return subband_weights.reshape(nr_antennas, N_subbands * VALUES_PER_COMPLEX)
+        return subband_weights.reshape(nr_antennas * N_pol, N_subbands * VALUES_PER_COMPLEX)
 
     def _rcu_band_to_calibration_table(self) -> dict:
         """
@@ -507,7 +511,7 @@ class AntennaField(lofar_device):
 
         # reshape them into their actual form
         for band, caltable in rcu_band_to_caltable.items():
-            rcu_band_to_caltable[band] = numpy.array(caltable).reshape(nr_antennas, N_subbands, 2)
+            rcu_band_to_caltable[band] = numpy.array(caltable).reshape(nr_antennas, N_pol, N_subbands, 2)
 
         return rcu_band_to_caltable
 
@@ -526,7 +530,7 @@ class AntennaField(lofar_device):
         # construct the subband weights based on the rcu_band of each antenna,
         # combining the relevant tables.
         nr_antennas = self.read_attribute("nr_antennas_R")
-        subband_weights = numpy.zeros((nr_antennas, N_subbands, VALUES_PER_COMPLEX), dtype=numpy.float64)
+        subband_weights = numpy.zeros((nr_antennas, N_pol, N_subbands, VALUES_PER_COMPLEX), dtype=numpy.float64)
         for antenna_nr, rcu_band in enumerate(rcu_bands):
             # Skip antennas not connected to RECV. These do not have a valid RCU band selected.
             if recvs[antenna_nr] == 0:
@@ -536,9 +540,9 @@ class AntennaField(lofar_device):
             if antenna_to_sdp_mapping[antenna_nr, 1] == -1:
                 continue
 
-            subband_weights[antenna_nr, :, :] = rcu_band_to_caltable[rcu_band][antenna_nr, :, :]
+            subband_weights[antenna_nr, :, :, :] = rcu_band_to_caltable[rcu_band][antenna_nr, :, :, :]
 
-        return subband_weights.reshape(nr_antennas, N_subbands * VALUES_PER_COMPLEX)
+        return subband_weights.reshape(nr_antennas * N_pol, N_subbands * VALUES_PER_COMPLEX)
 
     def read_Calibration_RCU_Attenuation_dB_R(self):
         # Correct for signal loss in the cables
@@ -815,7 +819,8 @@ class AntennaField(lofar_device):
                 continue
 
             # set weights
-            fpga_subband_weights[fpga_nr, input_nr, :] = real_imag_to_weights(caltable[antenna_nr, :], SDP.SUBBAND_UNIT_WEIGHT)
+            fpga_subband_weights[fpga_nr, input_nr * N_pol + 0, :] = real_imag_to_weights(caltable[antenna_nr * N_pol + 0, :], SDP.SUBBAND_UNIT_WEIGHT)
+            fpga_subband_weights[fpga_nr, input_nr * N_pol + 1, :] = real_imag_to_weights(caltable[antenna_nr * N_pol + 1, :], SDP.SUBBAND_UNIT_WEIGHT)
         self.sdp_proxy.FPGA_subband_weights_RW = fpga_subband_weights.reshape(N_pn, S_pn * N_subbands)
 
 
diff --git a/tangostationcontrol/tangostationcontrol/devices/sdp/sdp.py b/tangostationcontrol/tangostationcontrol/devices/sdp/sdp.py
index 677b82e0f3fd9e241ab12c32433ad7d45a44dcde..4226d1d121d5be449900d0976def367513cdb5af 100644
--- a/tangostationcontrol/tangostationcontrol/devices/sdp/sdp.py
+++ b/tangostationcontrol/tangostationcontrol/devices/sdp/sdp.py
@@ -137,6 +137,8 @@ class SDP(opcua_device):
     FPGA_sdp_info_observation_id_RW = attribute_wrapper(comms_annotation=["FPGA_sdp_info_observation_id_RW"], datatype=numpy.uint32, dims=(N_pn,), access=AttrWriteType.READ_WRITE)
     FPGA_sdp_info_station_id_R = attribute_wrapper(comms_annotation=["FPGA_sdp_info_station_id_R"], datatype=numpy.uint32, dims=(N_pn,))
     FPGA_sdp_info_station_id_RW = attribute_wrapper(comms_annotation=["FPGA_sdp_info_station_id_RW"], datatype=numpy.uint32, dims=(N_pn,), access=AttrWriteType.READ_WRITE)
+    FPGA_subband_spectral_inversion_R = attribute_wrapper(comms_annotation=["FPGA_subband_spectral_inversion_R"], datatype=bool, dims=(N_pn,))
+    FPGA_subband_spectral_inversion_RW = attribute_wrapper(comms_annotation=["FPGA_subband_spectral_inversion_RW"], datatype=bool, dims=(N_pn,), access=AttrWriteType.READ_WRITE)
     FPGA_subband_weights_R = attribute_wrapper(comms_annotation=["FPGA_subband_weights_R"], datatype=numpy.uint32, dims=(N_pn, S_pn, N_subbands))
     FPGA_subband_weights_RW = attribute_wrapper(comms_annotation=["FPGA_subband_weights_RW"], datatype=numpy.uint32, dims=(N_pn, S_pn, N_subbands), access=AttrWriteType.READ_WRITE)
     FPGA_time_since_last_pps_R = attribute_wrapper(comms_annotation=["FPGA_time_since_last_pps_R"], datatype=numpy.float_, dims=(N_pn,))
diff --git a/tangostationcontrol/tangostationcontrol/integration_test/default/devices/test_device_antennafield.py b/tangostationcontrol/tangostationcontrol/integration_test/default/devices/test_device_antennafield.py
index 14002bca5b81ccfec845bf3291b986c6c8fd34da..1fdb815c93a8744ed791f0d9cfaa3cd8b3861a61 100644
--- a/tangostationcontrol/tangostationcontrol/integration_test/default/devices/test_device_antennafield.py
+++ b/tangostationcontrol/tangostationcontrol/integration_test/default/devices/test_device_antennafield.py
@@ -15,7 +15,7 @@ from tangostationcontrol.devices.antennafield import AntennaQuality, AntennaUse
 from tangostationcontrol.devices.sdp.common import weight_to_complex
 from tangostationcontrol.devices.sdp.sdp import SDP
 from .base import AbstractTestBases
-from tangostationcontrol.common.constants import N_elements, MAX_ANTENNA, N_pol, N_rcu, N_rcu_inp, DEFAULT_N_HBA_TILES, CLK_200_MHZ, N_pn, S_pn, N_subbands
+from tangostationcontrol.common.constants import N_elements, MAX_ANTENNA, N_pol, N_rcu, N_rcu_inp, DEFAULT_N_HBA_TILES, CLK_200_MHZ, N_pn, A_pn, N_subbands
 
 class TestAntennaFieldDevice(AbstractTestBases.TestDeviceBase):
 
@@ -352,12 +352,17 @@ class TestAntennaFieldDevice(AbstractTestBases.TestDeviceBase):
         # and on the exact delay and loss differences between the cables.
         # rather than repeating the computations from the code,
         # we implement this as a regression test.
-        subband_weights = self.sdp_proxy.FPGA_subband_weights_RW.reshape(N_pn, S_pn, N_subbands)
+        subband_weights = self.sdp_proxy.FPGA_subband_weights_RW.reshape(N_pn, A_pn, N_pol, N_subbands)
 
         def to_complex(weight):
             return weight_to_complex(weight, SDP.SUBBAND_UNIT_WEIGHT)
 
-        self.assertAlmostEqual(0.929 + 0j,     to_complex(subband_weights[0, 0,   0]), places=3)
-        self.assertAlmostEqual(0.309 + 0.876j, to_complex(subband_weights[0, 0, 511]), places=3)
-        self.assertAlmostEqual(0.989 + 0j,     to_complex(subband_weights[0, 1,   0]), places=3)
-        self.assertAlmostEqual(0.883 - 0.444j, to_complex(subband_weights[0, 1, 511]), places=3)
+        # weight should be equal for both polarisations, different per antenna
+        self.assertAlmostEqual(0.929 + 0j,     to_complex(subband_weights[0, 0, 0,   0]), places=3)
+        self.assertAlmostEqual(0.309 + 0.876j, to_complex(subband_weights[0, 0, 0, 511]), places=3)
+        self.assertAlmostEqual(0.929 + 0j,     to_complex(subband_weights[0, 0, 1,   0]), places=3)
+        self.assertAlmostEqual(0.309 + 0.876j, to_complex(subband_weights[0, 0, 1, 511]), places=3)
+        self.assertAlmostEqual(0.989 + 0j,     to_complex(subband_weights[0, 1, 0,   0]), places=3)
+        self.assertAlmostEqual(0.883 - 0.444j, to_complex(subband_weights[0, 1, 0, 511]), places=3)
+        self.assertAlmostEqual(0.989 + 0j,     to_complex(subband_weights[0, 1, 1,   0]), places=3)
+        self.assertAlmostEqual(0.883 - 0.444j, to_complex(subband_weights[0, 1, 1, 511]), places=3)
diff --git a/tangostationcontrol/tangostationcontrol/integration_test/default/statistics/test_writer_sst.py b/tangostationcontrol/tangostationcontrol/integration_test/default/statistics/test_writer_sst.py
index cac23a518c77d20ed0a339b64e63a9af2c6dd9ef..cc9576c5327019b334463e6c173f4dea6a737af5 100644
--- a/tangostationcontrol/tangostationcontrol/integration_test/default/statistics/test_writer_sst.py
+++ b/tangostationcontrol/tangostationcontrol/integration_test/default/statistics/test_writer_sst.py
@@ -82,7 +82,7 @@ class TestStatisticsWriterSST(BaseIntegrationTestCase):
                     '2021-09-20T12:17:40.000+00:00'
                 )
                 self.assertIsNotNone(stat)
-                self.assertEqual("0.4.0", stat.station_version_id)
+                self.assertEqual("0.4.1", stat.station_version_id)
                 self.assertEqual("0.1", stat.writer_version_id)
 
     def test_insert_tango_SST_statistics(self):