diff --git a/tangostationcontrol/tangostationcontrol/clients/attribute_wrapper.py b/tangostationcontrol/tangostationcontrol/clients/attribute_wrapper.py
index ee898ff561ea916431a7100f098069c68b4e5a13..46589552326436c926c98750b91b9b42b8b52d4f 100644
--- a/tangostationcontrol/tangostationcontrol/clients/attribute_wrapper.py
+++ b/tangostationcontrol/tangostationcontrol/clients/attribute_wrapper.py
@@ -89,22 +89,26 @@ class attribute_wrapper(attribute):
         self.datatype = datatype
 
         if dims == (1,):
+            # scalar
             # Tango defines a scalar as having dimensions (1,0), see https://pytango.readthedocs.io/en/stable/server_api/attribute.html
             max_dim_x = 1
             max_dim_y = 0
             dtype = datatype
             shape = ()
         elif len(dims) == 1:
+            # spectrum
             max_dim_x = dims[0]
             max_dim_y = 0
             dtype = (datatype,)
             shape = (max_dim_x,)
         elif len(dims) == 2:
+            # image
             max_dim_x = dims[1]
             max_dim_y = dims[0]
             dtype = ((datatype,),)
             shape = (max_dim_y, max_dim_x)
         else:
+            # higher dimensional
             # >2D arrays collapse into the X and Y dimensions. The Y (major) dimension mirrors the first dimension given, the
             # rest collapses into the X (minor) dimension.
             max_dim_x = reduce(mul, dims[1:])
diff --git a/tangostationcontrol/tangostationcontrol/clients/statistics/client.py b/tangostationcontrol/tangostationcontrol/clients/statistics/client.py
index 8cbcffc445fc2d3124e11f1f1f42ced225860c23..9ea336ad9e81df319f8596ab76d3b6080db7f567 100644
--- a/tangostationcontrol/tangostationcontrol/clients/statistics/client.py
+++ b/tangostationcontrol/tangostationcontrol/clients/statistics/client.py
@@ -15,6 +15,7 @@ from tangostationcontrol.clients.comms_client import AsyncCommClient
 from tangostationcontrol.clients.tcp_replicator import TCPReplicator
 from tangostationcontrol.clients.udp_receiver import UDPReceiver
 from tangostationcontrol.clients.statistics.consumer import StatisticsConsumer
+from tangostationcontrol.common.constants import constants
 
 logger = logging.getLogger()
 
@@ -25,7 +26,7 @@ class StatisticsClient(AsyncCommClient):
       and provides a CommClient interface to expose points to a Device Server.
     """
 
-    def __init__(self, collector, udp_options, tcp_options, fault_func, event_loop=None, queuesize=1024):
+    def __init__(self, collector, udp_options, tcp_options, fault_func, event_loop=None, queuesize=constants.STATISTICS_CLIENT_QUEUE_SIZE):
         """
         Create the statistics client and connect() to it and get the object node.
 
diff --git a/tangostationcontrol/tangostationcontrol/clients/udp_receiver.py b/tangostationcontrol/tangostationcontrol/clients/udp_receiver.py
index fbe17bc22ffde29bc90adfb036193590617c0990..585655172530fa7efbacc32c576f76362cb4785f 100644
--- a/tangostationcontrol/tangostationcontrol/clients/udp_receiver.py
+++ b/tangostationcontrol/tangostationcontrol/clients/udp_receiver.py
@@ -90,7 +90,7 @@ class UDPReceiver(Thread, StatisticsClientThread):
 
         while self.stream_on:
             try:
-                packet, _, _, _ = self.sock.recvmsg(9000)
+                packet, _, _, _ = self.sock.recvmsg(constants.MAX_PACKET_SIZE)
 
                 self.parameters["nof_packets_received"]  += numpy.uint64(1)
                 self.parameters["nof_bytes_received"]    += numpy.uint64(len(packet))
diff --git a/tangostationcontrol/tangostationcontrol/common/constants.py b/tangostationcontrol/tangostationcontrol/common/constants.py
index cc0a3a0f14595bb0dc946fb531ab347de6bd04c6..69dc7c2f435838fc620b90d7491ca36732ed3397 100644
--- a/tangostationcontrol/tangostationcontrol/common/constants.py
+++ b/tangostationcontrol/tangostationcontrol/common/constants.py
@@ -48,7 +48,8 @@ class constants:
 
     N_beamsets_sdp = 2
     N_beamsets_ctrl = 1
-    N_beamlets_sdp = 976
+    # The maximum amount of beamlets the SDP (and we) support
+    N_beamlets_max = 976
     # number of actively controlled beamlets
     N_beamlets_ctrl = 488
     N_beamlets_out = 488
@@ -61,11 +62,23 @@ class constants:
     # Maximum array size to allocate for beam_device pointings,
     MAX_POINTINGS = 1024
 
+    # Maximum number of antenna inputs we support (used to determine array sizes)
+    MAX_INPUTS = 192
+    # Maximum number of subbands for which we collect XSTs simultaneously
+    MAX_PARALLEL_SUBBANDS = 8
+    # Expected block for XST's
+    BLOCK_LENGTH = 12
+    # Complex values are (real, imag). A bit silly, but we don't want magical
+    VALUES_PER_COMPLEX = 2
+    # Max blocks for the BST statistics
+    MAX_BLOCKS = 2
+
     # number of sockets the psoc has
     PSOC_SOCKETS = 8
 
     # main clock frequency of the subrack is 200MHz NOTE: type is a float here
-    F_CLOCK = 200e6
+    CLK_200 = 200_000_000
+    CLK_160 = 160_000_000
 
     # default subband we use because of its low RFI
     DEFAULT_SUBBAND = 102
@@ -86,12 +99,21 @@ class constants:
     # Maximum number of supported simultaneous replicator clients
     MAX_STATISTICS_CLIENTS = 128
 
+    # the maximum amount of packets unhandled packets the statistics client thread will queue
+    STATISTICS_CLIENT_QUEUE_SIZE = 1024
+
     # maximum number of devices boot.py supports
     MAX_BOOT_DEVICES = 128
 
     # The default polling period for polled attributes
     DEFAULT_POLLING_PERIOD = 1000
 
+    # the three spatial dimensions XYZ used a lot for pointing directions and ITRF coordinates.
+    N_xyz = 3
+    # number of values for latitude/longitude coordinates
+    N_coord = 2
+
+
 """
 These classes for now exist for future use
 
diff --git a/tangostationcontrol/tangostationcontrol/devices/antennafield.py b/tangostationcontrol/tangostationcontrol/devices/antennafield.py
index 59b0d076c09d764da7b52176d908cafbd3322749..fbd4506ebec411d37ccda3ac855f2756239fc784 100644
--- a/tangostationcontrol/tangostationcontrol/devices/antennafield.py
+++ b/tangostationcontrol/tangostationcontrol/devices/antennafield.py
@@ -235,41 +235,41 @@ class AntennaField(lofar_device):
     ANT_mask_RW                  = mapped_attribute("ANT_mask_RW", dtype=(bool,), max_dim_x=MAX_NUMBER_OF_HBAT, access=AttrWriteType.READ_WRITE)
     RCU_PWR_ANT_on_R             = mapped_attribute("RCU_PWR_ANT_on_R", dtype=(bool,), max_dim_x=MAX_NUMBER_OF_HBAT)
     RCU_PWR_ANT_on_RW            = mapped_attribute("RCU_PWR_ANT_on_RW", dtype=(bool,), max_dim_x=MAX_NUMBER_OF_HBAT, access=AttrWriteType.READ_WRITE)
-    HBAT_BF_delay_steps_R        = mapped_attribute("HBAT_BF_delay_steps_R", dtype=((numpy.int64,),), max_dim_x=NUMBER_OF_ELEMENTS_PER_TILE * 2, max_dim_y=MAX_NUMBER_OF_HBAT)
-    HBAT_BF_delay_steps_RW       = mapped_attribute("HBAT_BF_delay_steps_RW", dtype=((numpy.int64,),), max_dim_x=NUMBER_OF_ELEMENTS_PER_TILE * 2, max_dim_y=MAX_NUMBER_OF_HBAT, access=AttrWriteType.READ_WRITE)
-    HBAT_LED_on_R                = mapped_attribute("HBAT_LED_on_R", dtype=((bool,),), max_dim_x=NUMBER_OF_ELEMENTS_PER_TILE * 2, max_dim_y=MAX_NUMBER_OF_HBAT)
-    HBAT_LED_on_RW               = mapped_attribute("HBAT_LED_on_RW", dtype=((bool,),), max_dim_x=NUMBER_OF_ELEMENTS_PER_TILE * 2, max_dim_y=MAX_NUMBER_OF_HBAT, access=AttrWriteType.READ_WRITE)
-    HBAT_PWR_LNA_on_R            = mapped_attribute("HBAT_PWR_LNA_on_R", dtype=((bool,),), max_dim_x=NUMBER_OF_ELEMENTS_PER_TILE * 2, max_dim_y=MAX_NUMBER_OF_HBAT)
-    HBAT_PWR_LNA_on_RW           = mapped_attribute("HBAT_PWR_LNA_on_RW", dtype=((bool,),), max_dim_x=NUMBER_OF_ELEMENTS_PER_TILE * 2, max_dim_y=MAX_NUMBER_OF_HBAT, access=AttrWriteType.READ_WRITE)
-    HBAT_PWR_on_R                = mapped_attribute("HBAT_PWR_on_R", dtype=((bool,),), max_dim_x=NUMBER_OF_ELEMENTS_PER_TILE * 2, max_dim_y=MAX_NUMBER_OF_HBAT)
-    HBAT_PWR_on_RW               = mapped_attribute("HBAT_PWR_on_RW", dtype=((bool,),), max_dim_x=NUMBER_OF_ELEMENTS_PER_TILE * 2, max_dim_y=MAX_NUMBER_OF_HBAT, access=AttrWriteType.READ_WRITE)
+    HBAT_BF_delay_steps_R        = mapped_attribute("HBAT_BF_delay_steps_R", dtype=((numpy.int64,),), max_dim_x=NUMBER_OF_ELEMENTS_PER_TILE * constants.N_pol, max_dim_y=MAX_NUMBER_OF_HBAT)
+    HBAT_BF_delay_steps_RW       = mapped_attribute("HBAT_BF_delay_steps_RW", dtype=((numpy.int64,),), max_dim_x=NUMBER_OF_ELEMENTS_PER_TILE * constants.N_pol, max_dim_y=MAX_NUMBER_OF_HBAT, access=AttrWriteType.READ_WRITE)
+    HBAT_LED_on_R                = mapped_attribute("HBAT_LED_on_R", dtype=((bool,),), max_dim_x=NUMBER_OF_ELEMENTS_PER_TILE * constants.N_pol, max_dim_y=MAX_NUMBER_OF_HBAT)
+    HBAT_LED_on_RW               = mapped_attribute("HBAT_LED_on_RW", dtype=((bool,),), max_dim_x=NUMBER_OF_ELEMENTS_PER_TILE * constants.N_pol, max_dim_y=MAX_NUMBER_OF_HBAT, access=AttrWriteType.READ_WRITE)
+    HBAT_PWR_LNA_on_R            = mapped_attribute("HBAT_PWR_LNA_on_R", dtype=((bool,),), max_dim_x=NUMBER_OF_ELEMENTS_PER_TILE * constants.N_pol, max_dim_y=MAX_NUMBER_OF_HBAT)
+    HBAT_PWR_LNA_on_RW           = mapped_attribute("HBAT_PWR_LNA_on_RW", dtype=((bool,),), max_dim_x=NUMBER_OF_ELEMENTS_PER_TILE * constants.N_pol, max_dim_y=MAX_NUMBER_OF_HBAT, access=AttrWriteType.READ_WRITE)
+    HBAT_PWR_on_R                = mapped_attribute("HBAT_PWR_on_R", dtype=((bool,),), max_dim_x=NUMBER_OF_ELEMENTS_PER_TILE * constants.N_pol, max_dim_y=MAX_NUMBER_OF_HBAT)
+    HBAT_PWR_on_RW               = mapped_attribute("HBAT_PWR_on_RW", dtype=((bool,),), max_dim_x=NUMBER_OF_ELEMENTS_PER_TILE * constants.N_pol, max_dim_y=MAX_NUMBER_OF_HBAT, access=AttrWriteType.READ_WRITE)
     RCU_band_select_RW           = mapped_attribute("RCU_band_select_RW", dtype=(numpy.int64,), max_dim_x=MAX_NUMBER_OF_HBAT, access=AttrWriteType.READ_WRITE)
 
     # ----- Position information
 
     Antenna_Field_Reference_ITRF_R = attribute(access=AttrWriteType.READ,
-        doc='Absolute reference position of antenna field, in ITRF (XYZ)',
-        dtype=(numpy.float64,), max_dim_x=3)
+                                               doc='Absolute reference position of antenna field, in ITRF (XYZ)',
+                                               dtype=(numpy.float64,), max_dim_x=constants.N_xyz)
 
     Antenna_Field_Reference_GEO_R = attribute(access=AttrWriteType.READ,
         doc='Absolute reference position of antenna field, in latitude/longitude (degrees)',
-        dtype=(numpy.float64,), max_dim_x=2)
+        dtype=(numpy.float64,), max_dim_x=constants.N_coord)
 
     Antenna_Field_Reference_GEOHASH_R = attribute(access=AttrWriteType.READ,
         doc='Absolute reference position of antenna field, as a geohash string',
         dtype=str)
 
     HBAT_antenna_ITRF_offsets_R = attribute(access=AttrWriteType.READ,
-        doc='For each tile, the offsets of the antennas within that, in ITRF ("iHBADeltas"). True shape: nrtiles x 16 x 3.',
-        dtype=((numpy.float64,),), max_dim_x=NUMBER_OF_ELEMENTS_PER_TILE * 3, max_dim_y=96)
+                                            doc='For each tile, the offsets of the antennas within that, in ITRF ("iHBADeltas"). True shape: nrtiles x 16 x 3.',
+                                            dtype=((numpy.float64,),), max_dim_x=NUMBER_OF_ELEMENTS_PER_TILE * constants.N_xyz, max_dim_y=MAX_NUMBER_OF_HBAT)
 
     Antenna_Reference_ITRF_R = attribute(access=AttrWriteType.READ,
-        doc='Absolute reference position of each tile, in ITRF (XYZ)',
-        dtype=((numpy.float64,),), max_dim_x=3, max_dim_y=MAX_NUMBER_OF_HBAT)
+                                         doc='Absolute reference position of each tile, in ITRF (XYZ)',
+                                         dtype=((numpy.float64,),), max_dim_x=constants.N_xyz, max_dim_y=MAX_NUMBER_OF_HBAT)
 
     Antenna_Reference_GEO_R = attribute(access=AttrWriteType.READ,
         doc='Absolute reference position of each tile, in latitude/longitude (degrees)',
-        dtype=((numpy.float64,),), max_dim_x=2, max_dim_y=MAX_NUMBER_OF_HBAT)
+        dtype=((numpy.float64,),), max_dim_x=constants.N_coord, max_dim_y=MAX_NUMBER_OF_HBAT)
 
     Antenna_Reference_GEOHASH_R = attribute(access=AttrWriteType.READ,
         doc='Absolute reference position of each tile, as geohash strings',
@@ -317,10 +317,10 @@ class AntennaField(lofar_device):
     def read_Antenna_Field_Reference_ITRF_R(self):
         # provide ITRF field coordinates if they were configured
         if self.Antenna_Field_Reference_ITRF:
-            return numpy.array(self.Antenna_Field_Reference_ITRF).reshape(3)
+            return numpy.array(self.Antenna_Field_Reference_ITRF).reshape(constants.N_xyz)
 
         # calculate them from ETRS coordinates if not, using the configured ITRF reference
-        ETRS_coordinates = numpy.array(self.Antenna_Field_Reference_ETRS).reshape(3)
+        ETRS_coordinates = numpy.array(self.Antenna_Field_Reference_ETRS).reshape(constants.N_xyz)
         return ETRS_to_ITRF(ETRS_coordinates, self.ITRF_Reference_Frame, self.ITRF_Reference_Epoch)
 
     def read_Antenna_Field_Reference_GEO_R(self):
@@ -345,9 +345,9 @@ class AntennaField(lofar_device):
             tiles lie on the same plane in ITRF. """
 
         # the relative offsets between the elements is fixed in HBAT_base_antenna_offsets
-        base_antenna_offsets        = numpy.array(self.HBAT_base_antenna_offsets).reshape(constants.N_te, 3)
+        base_antenna_offsets        = numpy.array(self.HBAT_base_antenna_offsets).reshape(constants.N_te, constants.N_xyz)
 
-        PQR_to_ETRS_rotation_matrix = numpy.array(self.PQR_to_ETRS_rotation_matrix).reshape(3,3)
+        PQR_to_ETRS_rotation_matrix = numpy.array(self.PQR_to_ETRS_rotation_matrix).reshape(constants.N_xyz, constants.N_xyz)
 
         # each tile has its own rotation angle, resulting in different offsets per tile
         all_offsets = numpy.array(
@@ -357,15 +357,15 @@ class AntennaField(lofar_device):
                        PQR_to_ETRS_rotation_matrix)
                     for angle_deg in self.HBAT_PQR_rotation_angles_deg])
 
-        return all_offsets.reshape(-1, constants.N_te * 3)
+        return all_offsets.reshape(-1, constants.N_te * constants.N_xyz)
 
     def read_Antenna_Reference_ITRF_R(self):
         # provide ITRF coordinates if they were configured
         if self.Antenna_Reference_ITRF:
-            return numpy.array(self.Antenna_Reference_ITRF).reshape(-1,3)
+            return numpy.array(self.Antenna_Reference_ITRF).reshape(-1, constants.N_xyz)
 
         # calculate them from ETRS coordinates if not, using the configured ITRF reference
-        ETRS_coordinates = numpy.array(self.Antenna_Reference_ETRS).reshape(-1,3)
+        ETRS_coordinates = numpy.array(self.Antenna_Reference_ETRS).reshape(-1, constants.N_xyz)
         return ETRS_to_ITRF(ETRS_coordinates, self.ITRF_Reference_Frame, self.ITRF_Reference_Epoch)
 
     def read_Antenna_Reference_GEO_R(self):
@@ -450,8 +450,8 @@ class AntennaField(lofar_device):
 
         delays = delays.reshape(num_tiles, constants.N_te)
 
-        result_values = numpy.zeros((num_tiles, constants.N_te * 2), dtype=numpy.int64)
-        control_mapping = numpy.reshape(self.Control_to_RECV_mapping, (-1, 2))
+        result_values = numpy.zeros((num_tiles, constants.N_te * constants.N_pol_bf), dtype=numpy.int64)
+        control_mapping = numpy.reshape(self.Control_to_RECV_mapping, (-1, constants.N_pol_bf))
 
         for recv_idx, recv_proxy in enumerate(self.recv_proxies):
             # collect all delays for this recv_proxy
@@ -464,7 +464,7 @@ class AntennaField(lofar_device):
 
             # convert them into delay steps
             flatten_delay_steps = numpy.array(recv_proxy.calculate_HBAT_bf_delay_steps(recv_delays.flatten()), dtype=numpy.int64)
-            delay_steps = numpy.reshape(flatten_delay_steps, (-1, constants.N_te * 2))
+            delay_steps = numpy.reshape(flatten_delay_steps, (-1, constants.N_te * constants.N_pol))
 
             # write back into same positions we collected them from
             result_values[recv_result_indices] = delay_steps
diff --git a/tangostationcontrol/tangostationcontrol/devices/beam_device.py b/tangostationcontrol/tangostationcontrol/devices/beam_device.py
index 832df357230ce562e3b6e87cbf077b680b4e2978..4f64b44044ba2724aac3667c47eee33c10a5b13b 100644
--- a/tangostationcontrol/tangostationcontrol/devices/beam_device.py
+++ b/tangostationcontrol/tangostationcontrol/devices/beam_device.py
@@ -74,11 +74,11 @@ class beam_device(lofar_device):
     # will be stored as self._num_pointings.
 
     Pointing_direction_R = attribute(access=AttrWriteType.READ,
-        dtype=((str,),), max_dim_x=3, max_dim_y=constants.MAX_POINTINGS,
+        dtype=((str,),), max_dim_x=constants.N_xyz, max_dim_y=constants.MAX_POINTINGS,
         fget=lambda self: self._pointing_direction_r)
 
     Pointing_direction_RW = attribute(access=AttrWriteType.READ_WRITE,
-        dtype=((str,),), max_dim_x=3, max_dim_y=constants.MAX_POINTINGS,
+        dtype=((str,),), max_dim_x=constants.N_xyz, max_dim_y=constants.MAX_POINTINGS,
         fget=lambda self: self._pointing_direction_rw)
 
     Pointing_direction_str_R = attribute(access=AttrWriteType.READ,
@@ -230,7 +230,7 @@ class beam_device(lofar_device):
         # Initialise tracking control
         self._num_pointings            = num_pointings
         self._pointing_timestamp_r     = numpy.zeros(num_pointings, dtype=numpy.double)
-        self._pointing_direction_r     = numpy.zeros((num_pointings, 3), dtype="<U32")
+        self._pointing_direction_r     = numpy.zeros((num_pointings, constants.N_xyz), dtype="<U32")
         self._pointing_direction_rw    = numpy.array([["AZELGEO","0deg","90deg"]] * num_pointings, dtype="<U32")
         self._tracking_enabled_rw      = self.Tracking_enabled_RW_default
 
diff --git a/tangostationcontrol/tangostationcontrol/devices/sdp/beamlet.py b/tangostationcontrol/tangostationcontrol/devices/sdp/beamlet.py
index 4c42faea1da8b590a2be00fec75fb48e9d98995e..e86bd456220b85c2d2b3e3124e873e6a729929f4 100644
--- a/tangostationcontrol/tangostationcontrol/devices/sdp/beamlet.py
+++ b/tangostationcontrol/tangostationcontrol/devices/sdp/beamlet.py
@@ -293,7 +293,7 @@ class Beamlet(opcua_device):
     def _subband_frequencies(subbands: numpy.ndarray, clock: int, nyquist_zone: int) -> numpy.ndarray:
         """ Obtain the frequencies of each subband, given a clock and an antenna type. """
 
-        subband_width = clock / 1024
+        subband_width = clock / constants.N_fft
         base_subband  = nyquist_zone * constants.N_sub
 
         # broadcast clock across frequencies
diff --git a/tangostationcontrol/tangostationcontrol/devices/sdp/bst.py b/tangostationcontrol/tangostationcontrol/devices/sdp/bst.py
index e7f1cf4e27f30fa7d957312aa35fcecbaaf53737..016fa9c16adc5cba577f654fca11cc11916b7263 100644
--- a/tangostationcontrol/tangostationcontrol/devices/sdp/bst.py
+++ b/tangostationcontrol/tangostationcontrol/devices/sdp/bst.py
@@ -84,14 +84,14 @@ class BST(Statistics):
     FPGA_bst_offload_nof_valid_R = attribute_wrapper(comms_annotation=["FPGA_bst_offload_nof_valid_R"], datatype=numpy.int32, dims=(constants.N_pn,))
 
     # number of packets with valid payloads
-    nof_valid_payloads_R    = attribute_wrapper(comms_id=StatisticsClient, comms_annotation={"type": "statistics", "parameter": "nof_valid_payloads"}, dims=(BSTCollector.MAX_FPGAS,), datatype=numpy.uint64)
+    nof_valid_payloads_R    = attribute_wrapper(comms_id=StatisticsClient, comms_annotation={"type": "statistics", "parameter": "nof_valid_payloads"}, dims=(constants.N_pn,), datatype=numpy.uint64)
     # number of packets with invalid payloads
-    nof_payload_errors_R    = attribute_wrapper(comms_id=StatisticsClient, comms_annotation={"type": "statistics", "parameter": "nof_payload_errors"}, dims=(BSTCollector.MAX_FPGAS,), datatype=numpy.uint64)
+    nof_payload_errors_R    = attribute_wrapper(comms_id=StatisticsClient, comms_annotation={"type": "statistics", "parameter": "nof_payload_errors"}, dims=(constants.N_pn,), datatype=numpy.uint64)
     # latest BSTs
-    bst_R                   = attribute_wrapper(comms_id=StatisticsClient, comms_annotation={"type": "statistics", "parameter": "bst_values"}, dims=(BSTCollector.MAX_BLOCKS, BSTCollector.MAX_BEAMLETS), datatype=numpy.uint64)
+    bst_R                   = attribute_wrapper(comms_id=StatisticsClient, comms_annotation={"type": "statistics", "parameter": "bst_values"}, dims=(constants.MAX_BLOCKS, constants.N_beamlets_max), datatype=numpy.uint64)
     # reported timestamp
     # for each row in the latest BSTs
-    bst_timestamp_R         = attribute_wrapper(comms_id=StatisticsClient, comms_annotation={"type": "statistics", "parameter": "bst_timestamps"}, dims=(BSTCollector.MAX_BLOCKS,), datatype=numpy.uint64)
+    bst_timestamp_R         = attribute_wrapper(comms_id=StatisticsClient, comms_annotation={"type": "statistics", "parameter": "bst_timestamps"}, dims=(constants.MAX_BLOCKS,), datatype=numpy.uint64)
 
     # ----------
     # Summarising Attributes
diff --git a/tangostationcontrol/tangostationcontrol/devices/sdp/digitalbeam.py b/tangostationcontrol/tangostationcontrol/devices/sdp/digitalbeam.py
index a5a5c9d96e04b02c90a2c7e940f15e1a8f8101b4..633a8d56988d254674d5f46ea540e1935773c52b 100644
--- a/tangostationcontrol/tangostationcontrol/devices/sdp/digitalbeam.py
+++ b/tangostationcontrol/tangostationcontrol/devices/sdp/digitalbeam.py
@@ -144,7 +144,7 @@ class DigitalBeam(beam_device):
 
         # Retrieve positions from RECV device
         reference_itrf = self.antennafield_proxy.Antenna_Field_Reference_ITRF_R
-        antenna_itrf   = self.antennafield_proxy.Antenna_Reference_ITRF_R.reshape(-1, 3)
+        antenna_itrf   = self.antennafield_proxy.Antenna_Reference_ITRF_R.reshape(-1, constants.N_xyz)
 
         # Generate positions for all FPGA inputs.
         # Use reference position for any missing antennas so they always get a delay of 0
diff --git a/tangostationcontrol/tangostationcontrol/devices/sdp/sdp.py b/tangostationcontrol/tangostationcontrol/devices/sdp/sdp.py
index def422eb51f67c9ce052356afc48ed4c1fd9644d..4ede62a8c8e7042d3916abdd70b9f0b182d16baa 100644
--- a/tangostationcontrol/tangostationcontrol/devices/sdp/sdp.py
+++ b/tangostationcontrol/tangostationcontrol/devices/sdp/sdp.py
@@ -76,7 +76,7 @@ class SDP(opcua_device):
         dtype='DevVarDoubleArray',
         mandatory=False,
         # Emit a signal on subband 102
-        default_value=[[constants.DEFAULT_SUBBAND * constants.F_CLOCK / 1024] * S_pn] * N_pn
+        default_value=[[constants.DEFAULT_SUBBAND * float(constants.CLK_200) / constants.N_fft] * S_pn] * N_pn
     )
 
     FPGA_wg_phase_RW_default = device_property(
@@ -106,7 +106,7 @@ class SDP(opcua_device):
     clock_RW_default = device_property(
         dtype='DevULong',
         mandatory=False,
-        default_value = int(constants.F_CLOCK)
+        default_value = constants.CLK_200
     )
 
     TRANSLATOR_DEFAULT_SETTINGS = [
@@ -236,7 +236,7 @@ class SDP(opcua_device):
         return numpy.uint32(clocks_in_mask[0]) if clocks_in_mask else self.clock_RW_default
 
     def write_clock_RW(self, clock):
-        if clock not in (160*1000000, 200*1000000):
+        if clock not in (constants.CLK_160, constants.CLK_200):
             raise ValueError(f"Unsupported clock frequency: {clock}")
 
         # Tell all FPGAs to use this clock
diff --git a/tangostationcontrol/tangostationcontrol/devices/sdp/sst.py b/tangostationcontrol/tangostationcontrol/devices/sdp/sst.py
index cc0bc9b0687166edcc5f028346b3592b67d12576..0a7d7c8186d8d69d53011f2bd86b8a45ee5981bd 100644
--- a/tangostationcontrol/tangostationcontrol/devices/sdp/sst.py
+++ b/tangostationcontrol/tangostationcontrol/devices/sdp/sst.py
@@ -100,14 +100,14 @@ class SST(Statistics):
     # number of packets with invalid payloads
     nof_payload_errors_R    = attribute_wrapper(comms_id=StatisticsClient, comms_annotation={"type": "statistics", "parameter": "nof_payload_errors"}, dims=(constants.N_pn,), datatype=numpy.uint64)
     # latest SSTs
-    sst_R                   = attribute_wrapper(comms_id=StatisticsClient, comms_annotation={"type": "statistics", "parameter": "sst_values"}, dims=(StationSSTCollector.MAX_INPUTS, constants.N_sub), datatype=numpy.uint64)
+    sst_R                   = attribute_wrapper(comms_id=StatisticsClient, comms_annotation={"type": "statistics", "parameter": "sst_values"}, dims=(constants.MAX_INPUTS, constants.N_sub), datatype=numpy.uint64)
     # reported timestamp
     # for each row in the latest SSTs
-    sst_timestamp_R         = attribute_wrapper(comms_id=StatisticsClient, comms_annotation={"type": "statistics", "parameter": "sst_timestamps"}, dims=(StationSSTCollector.MAX_INPUTS,), datatype=numpy.uint64)
+    sst_timestamp_R         = attribute_wrapper(comms_id=StatisticsClient, comms_annotation={"type": "statistics", "parameter": "sst_timestamps"}, dims=(constants.MAX_INPUTS,), datatype=numpy.uint64)
     # integration interval for each row in the latest SSTs
-    integration_interval_R  = attribute_wrapper(comms_id=StatisticsClient, comms_annotation={"type": "statistics", "parameter": "integration_intervals"}, dims=(StationSSTCollector.MAX_INPUTS,), datatype=numpy.float32)
+    integration_interval_R  = attribute_wrapper(comms_id=StatisticsClient, comms_annotation={"type": "statistics", "parameter": "integration_intervals"}, dims=(constants.MAX_INPUTS,), datatype=numpy.float32)
     # whether the subband data was calibrated by the SDP (that is, were subband weights applied)
-    subbands_calibrated_R   = attribute_wrapper(comms_id=StatisticsClient, comms_annotation={"type": "statistics", "parameter": "subbands_calibrated"}, dims=(StationSSTCollector.MAX_INPUTS,), datatype=bool)
+    subbands_calibrated_R   = attribute_wrapper(comms_id=StatisticsClient, comms_annotation={"type": "statistics", "parameter": "subbands_calibrated"}, dims=(constants.MAX_INPUTS,), datatype=bool)
 
     # ----------
     # Summarising Attributes
diff --git a/tangostationcontrol/tangostationcontrol/devices/sdp/xst.py b/tangostationcontrol/tangostationcontrol/devices/sdp/xst.py
index b044bc84c7fd2e312fb9dbf9078029b832011ff7..42ead3ecf56a7965256c70eeeed92660b4c3f606 100644
--- a/tangostationcontrol/tangostationcontrol/devices/sdp/xst.py
+++ b/tangostationcontrol/tangostationcontrol/devices/sdp/xst.py
@@ -111,8 +111,8 @@ class XST(Statistics):
     FPGA_xst_offload_bsn_R = attribute_wrapper(comms_id=OPCUAConnection, comms_annotation=["FPGA_xst_offload_bsn_R"], datatype=numpy.int64, dims=(N_pn,))
     FPGA_xst_processing_enable_RW = attribute_wrapper(comms_id=OPCUAConnection, comms_annotation=["FPGA_xst_processing_enable_RW"], datatype=bool, dims=(N_pn,), access=AttrWriteType.READ_WRITE)
     FPGA_xst_processing_enable_R = attribute_wrapper(comms_id=OPCUAConnection, comms_annotation=["FPGA_xst_processing_enable_R"], datatype=bool, dims=(N_pn,))
-    FPGA_xst_subband_select_RW = attribute_wrapper(comms_id=OPCUAConnection, comms_annotation=["FPGA_xst_subband_select_RW"], datatype=numpy.uint32, dims=(XSTCollector.MAX_PARALLEL_SUBBANDS,N_pn), access=AttrWriteType.READ_WRITE)
-    FPGA_xst_subband_select_R = attribute_wrapper(comms_id=OPCUAConnection, comms_annotation=["FPGA_xst_subband_select_R"], datatype=numpy.uint32, dims=(XSTCollector.MAX_PARALLEL_SUBBANDS,N_pn))
+    FPGA_xst_subband_select_RW = attribute_wrapper(comms_id=OPCUAConnection, comms_annotation=["FPGA_xst_subband_select_RW"], datatype=numpy.uint32, dims=(constants.MAX_PARALLEL_SUBBANDS,N_pn), access=AttrWriteType.READ_WRITE)
+    FPGA_xst_subband_select_R = attribute_wrapper(comms_id=OPCUAConnection, comms_annotation=["FPGA_xst_subband_select_R"], datatype=numpy.uint32, dims=(constants.MAX_PARALLEL_SUBBANDS,N_pn))
 
     FPGA_xst_offload_nof_crosslets_RW = attribute_wrapper(comms_id=OPCUAConnection, comms_annotation=["FPGA_xst_offload_nof_crosslets_RW"], datatype=numpy.uint32, dims=(N_pn,), access=AttrWriteType.READ_WRITE)
     FPGA_xst_offload_nof_crosslets_R = attribute_wrapper(comms_id=OPCUAConnection, comms_annotation=["FPGA_xst_offload_nof_crosslets_R"], datatype=numpy.uint32, dims=(N_pn,))
@@ -149,78 +149,78 @@ class XST(Statistics):
     FPGA_xst_ring_tx_latency_R = attribute_wrapper(comms_id=OPCUAConnection, comms_annotation=["FPGA_xst_ring_tx_latency_R"], datatype=numpy.int32, dims=(N_pn,N_pn))
 
     # number of packets with valid payloads
-    nof_valid_payloads_R    = attribute_wrapper(comms_id=StatisticsClient, comms_annotation={"type": "statistics", "parameter": "nof_valid_payloads"}, dims=(XSTCollector.MAX_FPGAS,), datatype=numpy.uint64)
+    nof_valid_payloads_R    = attribute_wrapper(comms_id=StatisticsClient, comms_annotation={"type": "statistics", "parameter": "nof_valid_payloads"}, dims=(constants.N_pn,), datatype=numpy.uint64)
     # number of packets with invalid payloads
-    nof_payload_errors_R    = attribute_wrapper(comms_id=StatisticsClient, comms_annotation={"type": "statistics", "parameter": "nof_payload_errors"}, dims=(XSTCollector.MAX_FPGAS,), datatype=numpy.uint64)
+    nof_payload_errors_R    = attribute_wrapper(comms_id=StatisticsClient, comms_annotation={"type": "statistics", "parameter": "nof_payload_errors"}, dims=(constants.N_pn,), datatype=numpy.uint64)
     # latest XSTs
-    xst_blocks_R            = attribute_wrapper(comms_id=StatisticsClient, comms_annotation={"type": "statistics", "parameter": "xst_blocks", "reshape": True}, dims=(XSTCollector.MAX_PARALLEL_SUBBANDS, XSTCollector.MAX_BLOCKS, XSTCollector.BLOCK_LENGTH, XSTCollector.BLOCK_LENGTH, XSTCollector.VALUES_PER_COMPLEX), datatype=numpy.int64)
+    xst_blocks_R            = attribute_wrapper(comms_id=StatisticsClient, comms_annotation={"type": "statistics", "parameter": "xst_blocks", "reshape": True}, dims=(constants.MAX_PARALLEL_SUBBANDS, XSTCollector.MAX_BLOCKS, constants.BLOCK_LENGTH, constants.BLOCK_LENGTH, constants.VALUES_PER_COMPLEX), datatype=numpy.int64)
     # whether the values in the block are conjugated and transposed
-    xst_conjugated_R        = attribute_wrapper(comms_id=StatisticsClient, comms_annotation={"type": "statistics", "parameter": "xst_conjugated", "reshape": True}, dims=(XSTCollector.MAX_PARALLEL_SUBBANDS, XSTCollector.MAX_BLOCKS), datatype=bool)
+    xst_conjugated_R        = attribute_wrapper(comms_id=StatisticsClient, comms_annotation={"type": "statistics", "parameter": "xst_conjugated", "reshape": True}, dims=(constants.MAX_PARALLEL_SUBBANDS, XSTCollector.MAX_BLOCKS), datatype=bool)
     # reported timestamp for each subband in the latest XSTs
-    xst_timestamp_R         = attribute_wrapper(comms_id=StatisticsClient, comms_annotation={"type": "statistics", "parameter": "xst_timestamps"}, dims=(XSTCollector.MAX_PARALLEL_SUBBANDS,), datatype=numpy.uint64)
+    xst_timestamp_R         = attribute_wrapper(comms_id=StatisticsClient, comms_annotation={"type": "statistics", "parameter": "xst_timestamps"}, dims=(constants.MAX_PARALLEL_SUBBANDS,), datatype=numpy.uint64)
     # which subband the XSTs describe
-    xst_subbands_R          = attribute_wrapper(comms_id=StatisticsClient, comms_annotation={"type": "statistics", "parameter": "xst_subbands"}, dims=(XSTCollector.MAX_PARALLEL_SUBBANDS,), datatype=numpy.uint16)
+    xst_subbands_R          = attribute_wrapper(comms_id=StatisticsClient, comms_annotation={"type": "statistics", "parameter": "xst_subbands"}, dims=(constants.MAX_PARALLEL_SUBBANDS,), datatype=numpy.uint16)
     # integration interval for each subband in the latest XSTs
-    xst_integration_interval_R  = attribute_wrapper(comms_id=StatisticsClient, comms_annotation={"type": "statistics", "parameter": "xst_integration_intervals"}, dims=(XSTCollector.MAX_PARALLEL_SUBBANDS,), datatype=numpy.float32)
+    xst_integration_interval_R  = attribute_wrapper(comms_id=StatisticsClient, comms_annotation={"type": "statistics", "parameter": "xst_integration_intervals"}, dims=(constants.MAX_PARALLEL_SUBBANDS,), datatype=numpy.float32)
 
     # xst_R, but as a matrix of subband x (input x input)
-    xst_real_R              = attribute(max_dim_x=XSTCollector.MAX_INPUTS * XSTCollector.MAX_INPUTS, max_dim_y=XSTCollector.MAX_PARALLEL_SUBBANDS, dtype=((numpy.float32,),))
-    xst_imag_R              = attribute(max_dim_x=XSTCollector.MAX_INPUTS * XSTCollector.MAX_INPUTS, max_dim_y=XSTCollector.MAX_PARALLEL_SUBBANDS, dtype=((numpy.float32,),))
-    xst_power_R             = attribute(max_dim_x=XSTCollector.MAX_INPUTS * XSTCollector.MAX_INPUTS, max_dim_y=XSTCollector.MAX_PARALLEL_SUBBANDS, dtype=((numpy.float32,),))
-    xst_phase_R             = attribute(max_dim_x=XSTCollector.MAX_INPUTS * XSTCollector.MAX_INPUTS, max_dim_y=XSTCollector.MAX_PARALLEL_SUBBANDS, dtype=((numpy.float32,),))
+    xst_real_R              = attribute(max_dim_x=constants.MAX_INPUTS * constants.MAX_INPUTS, max_dim_y=constants.MAX_PARALLEL_SUBBANDS, dtype=((numpy.float32,),))
+    xst_imag_R              = attribute(max_dim_x=constants.MAX_INPUTS * constants.MAX_INPUTS, max_dim_y=constants.MAX_PARALLEL_SUBBANDS, dtype=((numpy.float32,),))
+    xst_power_R             = attribute(max_dim_x=constants.MAX_INPUTS * constants.MAX_INPUTS, max_dim_y=constants.MAX_PARALLEL_SUBBANDS, dtype=((numpy.float32,),))
+    xst_phase_R             = attribute(max_dim_x=constants.MAX_INPUTS * constants.MAX_INPUTS, max_dim_y=constants.MAX_PARALLEL_SUBBANDS, dtype=((numpy.float32,),))
 
     def read_xst_real_R(self):
-        return numpy.real(self.statistics_client.collector.xst_values()).reshape(XSTCollector.MAX_PARALLEL_SUBBANDS, XSTCollector.MAX_INPUTS * XSTCollector.MAX_INPUTS)
+        return numpy.real(self.statistics_client.collector.xst_values()).reshape(constants.MAX_PARALLEL_SUBBANDS, constants.MAX_INPUTS * constants.MAX_INPUTS)
 
     def read_xst_imag_R(self):
-        return numpy.imag(self.statistics_client.collector.xst_values()).reshape(XSTCollector.MAX_PARALLEL_SUBBANDS, XSTCollector.MAX_INPUTS * XSTCollector.MAX_INPUTS)
+        return numpy.imag(self.statistics_client.collector.xst_values()).reshape(constants.MAX_PARALLEL_SUBBANDS, constants.MAX_INPUTS * constants.MAX_INPUTS)
 
     def read_xst_power_R(self):
-        return numpy.abs(self.statistics_client.collector.xst_values()).reshape(XSTCollector.MAX_PARALLEL_SUBBANDS, XSTCollector.MAX_INPUTS * XSTCollector.MAX_INPUTS)
+        return numpy.abs(self.statistics_client.collector.xst_values()).reshape(constants.MAX_PARALLEL_SUBBANDS, constants.MAX_INPUTS * constants.MAX_INPUTS)
 
     def read_xst_phase_R(self):
-        return numpy.angle(self.statistics_client.collector.xst_values()).reshape(XSTCollector.MAX_PARALLEL_SUBBANDS, XSTCollector.MAX_INPUTS * XSTCollector.MAX_INPUTS)
+        return numpy.angle(self.statistics_client.collector.xst_values()).reshape(constants.MAX_PARALLEL_SUBBANDS, constants.MAX_INPUTS * constants.MAX_INPUTS)
 
     # xst_R, but as a matrix of input x input, for each specific subband index
-    xst_0_real_R            = attribute(max_dim_x=XSTCollector.MAX_INPUTS, max_dim_y=XSTCollector.MAX_INPUTS, dtype=((numpy.float32,),), fget = lambda self: self.read_xst_N_real_R(0))
-    xst_0_imag_R            = attribute(max_dim_x=XSTCollector.MAX_INPUTS, max_dim_y=XSTCollector.MAX_INPUTS, dtype=((numpy.float32,),), fget = lambda self: self.read_xst_N_imag_R(0))
-    xst_0_power_R           = attribute(max_dim_x=XSTCollector.MAX_INPUTS, max_dim_y=XSTCollector.MAX_INPUTS, dtype=((numpy.float32,),), fget = lambda self: self.read_xst_N_power_R(0))
-    xst_0_phase_R           = attribute(max_dim_x=XSTCollector.MAX_INPUTS, max_dim_y=XSTCollector.MAX_INPUTS, dtype=((numpy.float32,),), fget = lambda self: self.read_xst_N_phase_R(0))
-
-    xst_1_real_R            = attribute(max_dim_x=XSTCollector.MAX_INPUTS, max_dim_y=XSTCollector.MAX_INPUTS, dtype=((numpy.float32,),), fget = lambda self: self.read_xst_N_real_R(1))
-    xst_1_imag_R            = attribute(max_dim_x=XSTCollector.MAX_INPUTS, max_dim_y=XSTCollector.MAX_INPUTS, dtype=((numpy.float32,),), fget = lambda self: self.read_xst_N_imag_R(1))
-    xst_1_power_R           = attribute(max_dim_x=XSTCollector.MAX_INPUTS, max_dim_y=XSTCollector.MAX_INPUTS, dtype=((numpy.float32,),), fget = lambda self: self.read_xst_N_power_R(1))
-    xst_1_phase_R           = attribute(max_dim_x=XSTCollector.MAX_INPUTS, max_dim_y=XSTCollector.MAX_INPUTS, dtype=((numpy.float32,),), fget = lambda self: self.read_xst_N_phase_R(1))
-
-    xst_2_real_R            = attribute(max_dim_x=XSTCollector.MAX_INPUTS, max_dim_y=XSTCollector.MAX_INPUTS, dtype=((numpy.float32,),), fget = lambda self: self.read_xst_N_real_R(2))
-    xst_2_imag_R            = attribute(max_dim_x=XSTCollector.MAX_INPUTS, max_dim_y=XSTCollector.MAX_INPUTS, dtype=((numpy.float32,),), fget = lambda self: self.read_xst_N_imag_R(2))
-    xst_2_power_R           = attribute(max_dim_x=XSTCollector.MAX_INPUTS, max_dim_y=XSTCollector.MAX_INPUTS, dtype=((numpy.float32,),), fget = lambda self: self.read_xst_N_power_R(2))
-    xst_2_phase_R           = attribute(max_dim_x=XSTCollector.MAX_INPUTS, max_dim_y=XSTCollector.MAX_INPUTS, dtype=((numpy.float32,),), fget = lambda self: self.read_xst_N_phase_R(2))
-
-    xst_3_real_R            = attribute(max_dim_x=XSTCollector.MAX_INPUTS, max_dim_y=XSTCollector.MAX_INPUTS, dtype=((numpy.float32,),), fget = lambda self: self.read_xst_N_real_R(3))
-    xst_3_imag_R            = attribute(max_dim_x=XSTCollector.MAX_INPUTS, max_dim_y=XSTCollector.MAX_INPUTS, dtype=((numpy.float32,),), fget = lambda self: self.read_xst_N_imag_R(3))
-    xst_3_power_R           = attribute(max_dim_x=XSTCollector.MAX_INPUTS, max_dim_y=XSTCollector.MAX_INPUTS, dtype=((numpy.float32,),), fget = lambda self: self.read_xst_N_power_R(3))
-    xst_3_phase_R           = attribute(max_dim_x=XSTCollector.MAX_INPUTS, max_dim_y=XSTCollector.MAX_INPUTS, dtype=((numpy.float32,),), fget = lambda self: self.read_xst_N_phase_R(3))
-
-    xst_4_real_R            = attribute(max_dim_x=XSTCollector.MAX_INPUTS, max_dim_y=XSTCollector.MAX_INPUTS, dtype=((numpy.float32,),), fget = lambda self: self.read_xst_N_real_R(4))
-    xst_4_imag_R            = attribute(max_dim_x=XSTCollector.MAX_INPUTS, max_dim_y=XSTCollector.MAX_INPUTS, dtype=((numpy.float32,),), fget = lambda self: self.read_xst_N_imag_R(4))
-    xst_4_power_R           = attribute(max_dim_x=XSTCollector.MAX_INPUTS, max_dim_y=XSTCollector.MAX_INPUTS, dtype=((numpy.float32,),), fget = lambda self: self.read_xst_N_power_R(4))
-    xst_4_phase_R           = attribute(max_dim_x=XSTCollector.MAX_INPUTS, max_dim_y=XSTCollector.MAX_INPUTS, dtype=((numpy.float32,),), fget = lambda self: self.read_xst_N_phase_R(4))
-
-    xst_5_real_R            = attribute(max_dim_x=XSTCollector.MAX_INPUTS, max_dim_y=XSTCollector.MAX_INPUTS, dtype=((numpy.float32,),), fget = lambda self: self.read_xst_N_real_R(5))
-    xst_5_imag_R            = attribute(max_dim_x=XSTCollector.MAX_INPUTS, max_dim_y=XSTCollector.MAX_INPUTS, dtype=((numpy.float32,),), fget = lambda self: self.read_xst_N_imag_R(5))
-    xst_5_power_R           = attribute(max_dim_x=XSTCollector.MAX_INPUTS, max_dim_y=XSTCollector.MAX_INPUTS, dtype=((numpy.float32,),), fget = lambda self: self.read_xst_N_power_R(5))
-    xst_5_phase_R           = attribute(max_dim_x=XSTCollector.MAX_INPUTS, max_dim_y=XSTCollector.MAX_INPUTS, dtype=((numpy.float32,),), fget = lambda self: self.read_xst_N_phase_R(5))
-
-    xst_6_real_R            = attribute(max_dim_x=XSTCollector.MAX_INPUTS, max_dim_y=XSTCollector.MAX_INPUTS, dtype=((numpy.float32,),), fget = lambda self: self.read_xst_N_real_R(6))
-    xst_6_imag_R            = attribute(max_dim_x=XSTCollector.MAX_INPUTS, max_dim_y=XSTCollector.MAX_INPUTS, dtype=((numpy.float32,),), fget = lambda self: self.read_xst_N_imag_R(6))
-    xst_6_power_R           = attribute(max_dim_x=XSTCollector.MAX_INPUTS, max_dim_y=XSTCollector.MAX_INPUTS, dtype=((numpy.float32,),), fget = lambda self: self.read_xst_N_power_R(6))
-    xst_6_phase_R           = attribute(max_dim_x=XSTCollector.MAX_INPUTS, max_dim_y=XSTCollector.MAX_INPUTS, dtype=((numpy.float32,),), fget = lambda self: self.read_xst_N_phase_R(6))
-
-    xst_7_real_R            = attribute(max_dim_x=XSTCollector.MAX_INPUTS, max_dim_y=XSTCollector.MAX_INPUTS, dtype=((numpy.float32,),), fget = lambda self: self.read_xst_N_real_R(7))
-    xst_7_imag_R            = attribute(max_dim_x=XSTCollector.MAX_INPUTS, max_dim_y=XSTCollector.MAX_INPUTS, dtype=((numpy.float32,),), fget = lambda self: self.read_xst_N_imag_R(7))
-    xst_7_power_R           = attribute(max_dim_x=XSTCollector.MAX_INPUTS, max_dim_y=XSTCollector.MAX_INPUTS, dtype=((numpy.float32,),), fget = lambda self: self.read_xst_N_power_R(7))
-    xst_7_phase_R           = attribute(max_dim_x=XSTCollector.MAX_INPUTS, max_dim_y=XSTCollector.MAX_INPUTS, dtype=((numpy.float32,),), fget = lambda self: self.read_xst_N_phase_R(7))
+    xst_0_real_R            = attribute(max_dim_x=constants.MAX_INPUTS, max_dim_y=constants.MAX_INPUTS, dtype=((numpy.float32,),), fget = lambda self: self.read_xst_N_real_R(0))
+    xst_0_imag_R            = attribute(max_dim_x=constants.MAX_INPUTS, max_dim_y=constants.MAX_INPUTS, dtype=((numpy.float32,),), fget = lambda self: self.read_xst_N_imag_R(0))
+    xst_0_power_R           = attribute(max_dim_x=constants.MAX_INPUTS, max_dim_y=constants.MAX_INPUTS, dtype=((numpy.float32,),), fget = lambda self: self.read_xst_N_power_R(0))
+    xst_0_phase_R           = attribute(max_dim_x=constants.MAX_INPUTS, max_dim_y=constants.MAX_INPUTS, dtype=((numpy.float32,),), fget = lambda self: self.read_xst_N_phase_R(0))
+
+    xst_1_real_R            = attribute(max_dim_x=constants.MAX_INPUTS, max_dim_y=constants.MAX_INPUTS, dtype=((numpy.float32,),), fget = lambda self: self.read_xst_N_real_R(1))
+    xst_1_imag_R            = attribute(max_dim_x=constants.MAX_INPUTS, max_dim_y=constants.MAX_INPUTS, dtype=((numpy.float32,),), fget = lambda self: self.read_xst_N_imag_R(1))
+    xst_1_power_R           = attribute(max_dim_x=constants.MAX_INPUTS, max_dim_y=constants.MAX_INPUTS, dtype=((numpy.float32,),), fget = lambda self: self.read_xst_N_power_R(1))
+    xst_1_phase_R           = attribute(max_dim_x=constants.MAX_INPUTS, max_dim_y=constants.MAX_INPUTS, dtype=((numpy.float32,),), fget = lambda self: self.read_xst_N_phase_R(1))
+
+    xst_2_real_R            = attribute(max_dim_x=constants.MAX_INPUTS, max_dim_y=constants.MAX_INPUTS, dtype=((numpy.float32,),), fget = lambda self: self.read_xst_N_real_R(2))
+    xst_2_imag_R            = attribute(max_dim_x=constants.MAX_INPUTS, max_dim_y=constants.MAX_INPUTS, dtype=((numpy.float32,),), fget = lambda self: self.read_xst_N_imag_R(2))
+    xst_2_power_R           = attribute(max_dim_x=constants.MAX_INPUTS, max_dim_y=constants.MAX_INPUTS, dtype=((numpy.float32,),), fget = lambda self: self.read_xst_N_power_R(2))
+    xst_2_phase_R           = attribute(max_dim_x=constants.MAX_INPUTS, max_dim_y=constants.MAX_INPUTS, dtype=((numpy.float32,),), fget = lambda self: self.read_xst_N_phase_R(2))
+
+    xst_3_real_R            = attribute(max_dim_x=constants.MAX_INPUTS, max_dim_y=constants.MAX_INPUTS, dtype=((numpy.float32,),), fget = lambda self: self.read_xst_N_real_R(3))
+    xst_3_imag_R            = attribute(max_dim_x=constants.MAX_INPUTS, max_dim_y=constants.MAX_INPUTS, dtype=((numpy.float32,),), fget = lambda self: self.read_xst_N_imag_R(3))
+    xst_3_power_R           = attribute(max_dim_x=constants.MAX_INPUTS, max_dim_y=constants.MAX_INPUTS, dtype=((numpy.float32,),), fget = lambda self: self.read_xst_N_power_R(3))
+    xst_3_phase_R           = attribute(max_dim_x=constants.MAX_INPUTS, max_dim_y=constants.MAX_INPUTS, dtype=((numpy.float32,),), fget = lambda self: self.read_xst_N_phase_R(3))
+
+    xst_4_real_R            = attribute(max_dim_x=constants.MAX_INPUTS, max_dim_y=constants.MAX_INPUTS, dtype=((numpy.float32,),), fget = lambda self: self.read_xst_N_real_R(4))
+    xst_4_imag_R            = attribute(max_dim_x=constants.MAX_INPUTS, max_dim_y=constants.MAX_INPUTS, dtype=((numpy.float32,),), fget = lambda self: self.read_xst_N_imag_R(4))
+    xst_4_power_R           = attribute(max_dim_x=constants.MAX_INPUTS, max_dim_y=constants.MAX_INPUTS, dtype=((numpy.float32,),), fget = lambda self: self.read_xst_N_power_R(4))
+    xst_4_phase_R           = attribute(max_dim_x=constants.MAX_INPUTS, max_dim_y=constants.MAX_INPUTS, dtype=((numpy.float32,),), fget = lambda self: self.read_xst_N_phase_R(4))
+
+    xst_5_real_R            = attribute(max_dim_x=constants.MAX_INPUTS, max_dim_y=constants.MAX_INPUTS, dtype=((numpy.float32,),), fget = lambda self: self.read_xst_N_real_R(5))
+    xst_5_imag_R            = attribute(max_dim_x=constants.MAX_INPUTS, max_dim_y=constants.MAX_INPUTS, dtype=((numpy.float32,),), fget = lambda self: self.read_xst_N_imag_R(5))
+    xst_5_power_R           = attribute(max_dim_x=constants.MAX_INPUTS, max_dim_y=constants.MAX_INPUTS, dtype=((numpy.float32,),), fget = lambda self: self.read_xst_N_power_R(5))
+    xst_5_phase_R           = attribute(max_dim_x=constants.MAX_INPUTS, max_dim_y=constants.MAX_INPUTS, dtype=((numpy.float32,),), fget = lambda self: self.read_xst_N_phase_R(5))
+
+    xst_6_real_R            = attribute(max_dim_x=constants.MAX_INPUTS, max_dim_y=constants.MAX_INPUTS, dtype=((numpy.float32,),), fget = lambda self: self.read_xst_N_real_R(6))
+    xst_6_imag_R            = attribute(max_dim_x=constants.MAX_INPUTS, max_dim_y=constants.MAX_INPUTS, dtype=((numpy.float32,),), fget = lambda self: self.read_xst_N_imag_R(6))
+    xst_6_power_R           = attribute(max_dim_x=constants.MAX_INPUTS, max_dim_y=constants.MAX_INPUTS, dtype=((numpy.float32,),), fget = lambda self: self.read_xst_N_power_R(6))
+    xst_6_phase_R           = attribute(max_dim_x=constants.MAX_INPUTS, max_dim_y=constants.MAX_INPUTS, dtype=((numpy.float32,),), fget = lambda self: self.read_xst_N_phase_R(6))
+
+    xst_7_real_R            = attribute(max_dim_x=constants.MAX_INPUTS, max_dim_y=constants.MAX_INPUTS, dtype=((numpy.float32,),), fget = lambda self: self.read_xst_N_real_R(7))
+    xst_7_imag_R            = attribute(max_dim_x=constants.MAX_INPUTS, max_dim_y=constants.MAX_INPUTS, dtype=((numpy.float32,),), fget = lambda self: self.read_xst_N_imag_R(7))
+    xst_7_power_R           = attribute(max_dim_x=constants.MAX_INPUTS, max_dim_y=constants.MAX_INPUTS, dtype=((numpy.float32,),), fget = lambda self: self.read_xst_N_power_R(7))
+    xst_7_phase_R           = attribute(max_dim_x=constants.MAX_INPUTS, max_dim_y=constants.MAX_INPUTS, dtype=((numpy.float32,),), fget = lambda self: self.read_xst_N_phase_R(7))
 
     def read_xst_N_real_R(self, subband_idx):
         return numpy.real(self.statistics_client.collector.xst_values([subband_idx])[0])
diff --git a/tangostationcontrol/tangostationcontrol/devices/tilebeam.py b/tangostationcontrol/tangostationcontrol/devices/tilebeam.py
index 0e8a7fd947b60b76448d7a14e53365c30123a48f..c175963a3533163e888119d8d7ac811b410dab37 100644
--- a/tangostationcontrol/tangostationcontrol/devices/tilebeam.py
+++ b/tangostationcontrol/tangostationcontrol/devices/tilebeam.py
@@ -58,7 +58,7 @@ class TileBeam(beam_device):
 
         # Retrieve positions from AntennaField device
         Antenna_Reference_itrf = self.antennafield_proxy.Antenna_Reference_itrf_R
-        HBAT_antenna_itrf_offsets = self.antennafield_proxy.HBAT_antenna_itrf_offsets_R.reshape(self._nr_tiles, constants.N_te, 3)
+        HBAT_antenna_itrf_offsets = self.antennafield_proxy.HBAT_antenna_itrf_offsets_R.reshape(self._nr_tiles, constants.N_te, constants.N_xyz)
 
         # a delay calculator for each tile
         self.HBAT_delay_calculators = [Delays(reference_itrf) for reference_itrf in Antenna_Reference_itrf]