From 5a86b36ba06e46761bcedc51528ab4cddd97ec5c Mon Sep 17 00:00:00 2001
From: Jan David Mol <mol@astron.nl>
Date: Mon, 25 Jul 2022 11:07:44 +0200
Subject: [PATCH] Added custom LofarDeviceProxy to enhance support for
 high-dimensional arrays in attribtues

---
 lofar_station_client/device_proxy.py | 40 ++++++++++++++++++++++++++++
 requirements.txt                     |  1 +
 2 files changed, 41 insertions(+)
 create mode 100644 lofar_station_client/device_proxy.py

diff --git a/lofar_station_client/device_proxy.py b/lofar_station_client/device_proxy.py
new file mode 100644
index 0000000..18ebb3e
--- /dev/null
+++ b/lofar_station_client/device_proxy.py
@@ -0,0 +1,40 @@
+import ast
+from functools import lru_cache
+
+import numpy
+
+from tango import DeviceProxy
+from tango import ExtractAs
+
+
+class LofarDeviceProxy(DeviceProxy):
+    """A LOFAR-specific tango.DeviceProxy that provides
+    a richer experience."""
+
+    # cache attribute configurations, as they are not expected to change,
+    # but carry a cost to retrieve from the server.
+    @lru_cache()
+    def get_attribute_config(self, name):
+        return super().get_attribute_config(name)
+
+    def read_attribute(self, name, extract_as=ExtractAs.Numpy):
+        attr = super().read_attribute(name, extract_as)
+
+        # "format" property describes actual dimensions as a tuple (x, y, z, ...),
+        # so reshape the value accordingly.
+        fmt = self.get_attribute_config(name).format
+        if fmt and fmt[0] == "(" and isinstance(attr.value, numpy.ndarray):
+            shape = ast.literal_eval(fmt)
+            attr.value = attr.value.reshape(shape)
+
+        return attr
+
+    def write_attribute(self, name, value):
+        config = self.get_attribute_config(name)
+
+        # 2D arrays also represent arrays of higher dimensionality. reshape them
+        # to fit their original Tango shape before writing.
+        if config.max_dim_y > 0:
+            attr.value = attr.value.reshape((config.max_dim_y, config.max_dim_x))
+
+        return super().write_attribute(name, value)
diff --git a/requirements.txt b/requirements.txt
index ef6adef..3043b88 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -4,3 +4,4 @@ numpy>=1.21.0 # BSD
 nptyping>=2.3.0 # MIT
 matplotlib>=3.5.0 # PSF
 pyDeprecate>=0.3.0 # MIT
+tango # LGPLv3
-- 
GitLab