Skip to content
Snippets Groups Projects
Commit c11c7b94 authored by Jan David Mol's avatar Jan David Mol
Browse files

L2SS-1501: Also explicitly recalibrate if AntennaField changes state

parent 1c2a6154
Branches
Tags
1 merge request!727L2SS-1501: Also explicitly recalibrate if AntennaField changes state
......@@ -4,7 +4,9 @@
""" Calibration Device Server for LOFAR2.0
"""
import datetime
import logging
import numpy
from tango import EventType, Database
from tango.server import device_property, command, attribute
......@@ -42,13 +44,30 @@ class Calibration(LOFARDevice):
self.sdpfirmware_proxies: dict = {}
self.sdp_proxies: dict = {}
self.ant_proxies: dict = {}
self.last_ant_calibration_timestamp: dict[str, datetime.datetime | None] = {}
# Super must be called after variable assignment due to executing init_device!
super().__init__(cl, name)
def _calibrate_antenna_field(self, ant_proxy):
"""Recalibrate a specific AntennaField."""
if ant_proxy.state() not in DEFAULT_COMMAND_STATES:
logger.warning(
f"Device {ant_proxy.name()} not active. Forgoing calibration."
)
return
logger.info("Re-calibrate antenna field %s", ant_proxy.name())
self.last_ant_calibration_timestamp[ant_proxy] = datetime.datetime.now()
self.calibrate_recv(ant_proxy)
self.calibrate_sdp(ant_proxy)
@log_exceptions()
def _frequency_band_changed_event(self, event):
"""Trigger on external changes in frequency settings."""
def _antennafield_changed_event(self, event):
"""Trigger on key external changes in AntennaField settings."""
if event.err:
# little we can do here. note that errors are also
......@@ -63,13 +82,11 @@ class Calibration(LOFARDevice):
)
if self.dev_state() not in DEFAULT_COMMAND_STATES:
logger.warning("Device not active. Ignore frequency band changed event")
logger.warning("Device not active. Ignore AntennaField changed event")
return
# frequencies changed, so we need to recalibrate
logger.info("Re-calibrate antenna field %s", event.device.name())
self.calibrate_recv(event.device)
self.calibrate_sdp(event.device)
self._calibrate_antenna_field(event.device)
@log_exceptions()
def _clock_changed_event(self, event):
......@@ -91,12 +108,12 @@ class Calibration(LOFARDevice):
return
for k, ant in self.ant_proxies.items():
# Recalibrate associated AntennaFields
sdpfirmware_device = ant.SDPFirmware_device_R.casefold()
sdp_device = self.sdpfirmware_proxies[sdpfirmware_device].SDP_device_R
if device_name_matches(sdp_device, event.device.name()):
logger.info("Re-calibrate antenna field %s", k)
self.calibrate_sdp(k)
self.calibrate_recv(k)
self._calibrate_antenna_field(k)
# TODO(JDM): While we could read this from our control parent (StationManager),
# doing so creates a deadlock when StationManager wants to initialise this
......@@ -121,16 +138,29 @@ class Calibration(LOFARDevice):
def AntennaFields_Monitored_R(self):
return list(self.ant_proxies.keys())
@attribute(dtype=(numpy.int64,), max_dim_x=20)
def Last_AntennaField_Calibration_Timestamp_R(self):
return numpy.array(
[
ts.timestamp() if ts else 0
for ts in self.last_ant_calibration_timestamp.values()
],
dtype=numpy.int64,
)
@attribute(dtype=(str,), max_dim_x=20)
def SDPs_Monitored_R(self):
return list(self.sdp_proxies.keys())
@command
@command()
@only_in_states(DEFAULT_COMMAND_STATES)
def download_calibration_tables(self):
"""Download the latest calibration tables and apply them."""
self._calibration_manager.sync_calibration_tables()
for ant in self.ant_proxies.keys():
self.calibrate_recv(ant)
self.calibrate_sdp(ant)
# Apply downloaded tables
self.calibrate_all()
@command(dtype_in=str)
@only_in_states(DEFAULT_COMMAND_STATES)
......@@ -200,8 +230,7 @@ class Calibration(LOFARDevice):
logger.info("Re-calibrate antenna field %s", k)
try:
self.calibrate_sdp(k)
self.calibrate_recv(k)
self._calibrate_antenna_field(k)
except Exception as exc:
logger.exception("Could not calibrate antenna field %s", k)
......@@ -221,6 +250,7 @@ class Calibration(LOFARDevice):
for d in devices:
logger.debug("found antenna field device %s", str(d))
self.ant_proxies = {d.casefold(): create_device_proxy(d) for d in devices}
self.last_ant_calibration_timestamp = {d.casefold(): None for d in devices}
devices = db.get_device_exported_for_class(SDPFirmware.__name__)
for d in devices:
......@@ -243,11 +273,24 @@ class Calibration(LOFARDevice):
prx.subscribe_event(
"Frequency_Band_RW",
EventType.CHANGE_EVENT,
self._frequency_band_changed_event,
self._antennafield_changed_event,
stateless=True,
),
)
)
self.event_subscriptions.append(
(
prx,
prx.subscribe_event(
"State",
EventType.CHANGE_EVENT,
self._antennafield_changed_event,
stateless=True,
),
)
)
for prx in self.sdpfirmware_proxies.values():
self.event_subscriptions.append(
(
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment