diff --git a/CDB/stations/DTS_ConfigDb.json b/CDB/stations/DTS_ConfigDb.json index 84836d8e1c33e9619ff0b6a89ffa07a28f3b5bd3..69700d582a3e2366242da3a92c60244810e88ca7 100644 --- a/CDB/stations/DTS_ConfigDb.json +++ b/CDB/stations/DTS_ConfigDb.json @@ -164,6 +164,13 @@ "1", "28", "1", "29" ], + "Antenna_to_SDP_Mapping": [ + "0", "0", + "0", "1", + "0", "2", + "0", "3", + "0", "4" + ], "Antenna_Field_Reference_ETRS": [ "3839371.416", "430339.901", "5057958.886" ], @@ -196,24 +203,6 @@ "DigitalBeam": { "STAT/DigitalBeam/1": { "properties": { - "Input_to_Antenna_Mapping": [ - "0", "1", "2", "3", "4", "-1", - "-1", "-1", "-1", "-1", "-1", "-1", - "-1", "-1", "-1", "-1", "-1", "-1", - "-1", "-1", "-1", "-1", "-1", "-1", - "-1", "-1", "-1", "-1", "-1", "-1", - "-1", "-1", "-1", "-1", "-1", "-1", - "-1", "-1", "-1", "-1", "-1", "-1", - "-1", "-1", "-1", "-1", "-1", "-1", - "-1", "-1", "-1", "-1", "-1", "-1", - "-1", "-1", "-1", "-1", "-1", "-1", - "-1", "-1", "-1", "-1", "-1", "-1", - "-1", "-1", "-1", "-1", "-1", "-1", - "-1", "-1", "-1", "-1", "-1", "-1", - "-1", "-1", "-1", "-1", "-1", "-1", - "-1", "-1", "-1", "-1", "-1", "-1", - "-1", "-1", "-1", "-1", "-1", "-1" - ] } } } diff --git a/CDB/stations/DTS_Outside_ConfigDb.json b/CDB/stations/DTS_Outside_ConfigDb.json index 07ab30786c114b735b9b3660eac74a1d71080da1..baf9d0af986c343d90c68e7613a1933b32b531ca 100644 --- a/CDB/stations/DTS_Outside_ConfigDb.json +++ b/CDB/stations/DTS_Outside_ConfigDb.json @@ -196,6 +196,13 @@ "1","25", "1","26" ], + "Antenna_to_SDP_Mapping": [ + "3", "0", + "0", "-1", + "0", "-1", + "3", "1", + "3", "2" + ], "Antenna_Field_Reference_ETRS": [ "3839371.416","430339.901","5057958.886" ], @@ -258,6 +265,17 @@ "1","15", "1","17" ], + "Antenna_to_SDP_Mapping": [ + "0", "0", + "0", "1", + "0", "2", + "0", "3", + "0", "4", + "0", "5", + "1", "0", + "1", "1", + "1", "2" + ], "Antenna_Field_Reference_ETRS": [ "3839358.189", "430354.482", @@ -286,24 +304,6 @@ "properties": { "AntennaField_Device": [ "STAT/AntennaField/2" - ], - "Input_to_Antenna_Mapping": [ - "-1", "-1", "-1", "-1", "-1", "-1", - "-1", "-1", "-1", "-1", "-1", "-1", - "0", "3", "4", "-1", "-1", "-1", - "-1", "-1", "-1", "-1", "-1", "-1", - "-1", "-1", "-1", "-1", "-1", "-1", - "-1", "-1", "-1", "-1", "-1", "-1", - "-1", "-1", "-1", "-1", "-1", "-1", - "-1", "-1", "-1", "-1", "-1", "-1", - "-1", "-1", "-1", "-1", "-1", "-1", - "-1", "-1", "-1", "-1", "-1", "-1", - "-1", "-1", "-1", "-1", "-1", "-1", - "-1", "-1", "-1", "-1", "-1", "-1", - "-1", "-1", "-1", "-1", "-1", "-1", - "-1", "-1", "-1", "-1", "-1", "-1", - "-1", "-1", "-1", "-1", "-1", "-1", - "-1", "-1", "-1", "-1", "-1", "-1" ] } }, @@ -312,24 +312,6 @@ "AntennaField_Device": [ "STAT/AntennaField/1" ], - "Input_to_Antenna_Mapping": [ - "0", "1", "2", "3", "4", "5", - "6", "7", "8", "-1", "-1", "-1", - "-1", "-1", "-1", "-1", "-1", "-1", - "-1", "-1", "-1", "-1", "-1", "-1", - "-1", "-1", "-1", "-1", "-1", "-1", - "-1", "-1", "-1", "-1", "-1", "-1", - "-1", "-1", "-1", "-1", "-1", "-1", - "-1", "-1", "-1", "-1", "-1", "-1", - "-1", "-1", "-1", "-1", "-1", "-1", - "-1", "-1", "-1", "-1", "-1", "-1", - "-1", "-1", "-1", "-1", "-1", "-1", - "-1", "-1", "-1", "-1", "-1", "-1", - "-1", "-1", "-1", "-1", "-1", "-1", - "-1", "-1", "-1", "-1", "-1", "-1", - "-1", "-1", "-1", "-1", "-1", "-1", - "-1", "-1", "-1", "-1", "-1", "-1" - ], "Tracking_enabled_RW_default": [ "False" ] diff --git a/CDB/stations/dummy_6_positions_ConfigDb.json b/CDB/stations/dummy_6_positions_ConfigDb.json new file mode 100644 index 0000000000000000000000000000000000000000..a51ddb360baaf9f40b01e3830c3d6411ccbe61ee --- /dev/null +++ b/CDB/stations/dummy_6_positions_ConfigDb.json @@ -0,0 +1,81 @@ +{ + "servers": { + "AntennaField": { + "STAT": { + "AntennaField": { + "STAT/AntennaField/1": { + "properties": { + "RECV_devices": [ + "STAT/RECV/1" + ], + "Control_to_RECV_mapping": [ + "1", "0", + "1", "1", + "1", "2", + "1", "6", + "1", "7", + "1", "8" + ], + "Power_to_RECV_mapping": [ + "1", "3", + "1", "4", + "1", "5", + "1", "9", + "1", "10", + "1", "11" + ], + "Antenna_to_SDP_Mapping": [ + "0", "0", + "0", "1", + "0", "2", + "0", "3", + "0", "4", + "0", "5" + ], + "Antenna_Field_Reference_ETRS": [ + "3826896.631", "460979.131", "5064657.943" + ], + "HBAT_reference_ETRS": [ + "3826886.142", "460980.772", "5064665.668", + "3826887.237", "460985.643", "5064664.406", + "3826889.022", "460974.271", "5064664.094", + "3826890.118", "460979.142", "5064662.831", + "3826891.214", "460984.012", "5064661.568", + "3826892.311", "460988.883", "5064660.305" + ], + "HBAT_PQR_rotation_angles_deg": [ + "24", + "24", + "24", + "24", + "24", + "24" + ], + "PQR_to_ETRS_rotation_matrix": [ + "-0.1195951054", "-0.7919544517", "0.5987530018", + " 0.9928227484", "-0.0954186800", "0.0720990002", + " 0.0000330969", " 0.6030782884", "0.7976820024" + ] + } + } + } + } + }, + "DigitalBeam": { + "STAT": { + "DigitalBeam": { + "STAT/DigitalBeam/1": { + "properties": { + "Beam_tracking_interval": [ + "1.0" + ], + "Beam_tracking_preparation_period": [ + "0.5" + ] + } + } + } + } + } + } +} diff --git a/CDB/stations/dummy_positions_ConfigDb.json b/CDB/stations/dummy_positions_ConfigDb.json index 44f80657f8bd28a5dd9a885a7808c262d31b0d1c..b14187cc769a752a5fb49cede8695555ad26f2d8 100644 --- a/CDB/stations/dummy_positions_ConfigDb.json +++ b/CDB/stations/dummy_positions_ConfigDb.json @@ -105,6 +105,16 @@ "1", "94", "1", "95" ], + "Antenna_to_SDP_Mapping": [ + "0", "0", "0", "1", "0", "2", "0", "3", "0", "4", "0", "5", + "1", "0", "1", "1", "1", "2", "1", "3", "1", "4", "1", "5", + "2", "0", "2", "1", "2", "2", "2", "3", "2", "4", "2", "5", + "3", "0", "3", "1", "3", "2", "3", "3", "3", "4", "3", "5", + "4", "0", "4", "1", "4", "2", "4", "3", "4", "4", "4", "5", + "5", "0", "5", "1", "5", "2", "5", "3", "5", "4", "5", "5", + "6", "0", "6", "1", "6", "2", "6", "3", "6", "4", "6", "5", + "7", "0", "7", "1", "7", "2", "7", "3", "7", "4", "7", "5" + ], "Antenna_Field_Reference_ETRS": [ "3826896.631", "460979.131", "5064657.943" ], @@ -223,24 +233,6 @@ "DigitalBeam": { "STAT/DigitalBeam/1": { "properties": { - "Input_to_Antenna_Mapping": [ - "0", "1", "2", "3", "4", "5", - "6", "7", "8", "9", "10", "11", - "12", "13", "14", "15", "16", "17", - "18", "19", "20", "21", "22", "23", - "24", "25", "26", "27", "28", "29", - "30", "31", "32", "33", "34", "35", - "36", "37", "38", "39", "40", "41", - "42", "43", "44", "45", "46", "47", - "-1", "-1", "-1", "-1", "-1", "-1", - "-1", "-1", "-1", "-1", "-1", "-1", - "-1", "-1", "-1", "-1", "-1", "-1", - "-1", "-1", "-1", "-1", "-1", "-1", - "-1", "-1", "-1", "-1", "-1", "-1", - "-1", "-1", "-1", "-1", "-1", "-1", - "-1", "-1", "-1", "-1", "-1", "-1", - "-1", "-1", "-1", "-1", "-1", "-1" - ] } } } diff --git a/tangostationcontrol/tangostationcontrol/devices/antennafield.py b/tangostationcontrol/tangostationcontrol/devices/antennafield.py index b0a48fe25bf083bf7024fed5d9fcf0babedb49dd..308fccf86738df17082651550ab639c52300f4a9 100644 --- a/tangostationcontrol/tangostationcontrol/devices/antennafield.py +++ b/tangostationcontrol/tangostationcontrol/devices/antennafield.py @@ -187,6 +187,21 @@ class AntennaField(lofar_device): default_value = HBATAntennaOffsets.HBAT1_BASE_ANTENNA_OFFSETS.flatten() ) + # ----- SDP mapping + + Antenna_to_SDP_Mapping = device_property( + dtype=(numpy.int32,), + doc='The mapping of Antennas to FPGA input pairs. Each FPGA can handle 6 inputs, and SDP has 16 FPGAs. Each antenna is represented with a (fpga, input) value pair. The array is flattened, so must be reshaped upon use.', + default_value = [-1] * MAX_NUMBER_OF_HBAT * 2 + ) + + SDP_device = device_property( + dtype=str, + doc='Which SDP device is processing the AntennaField.', + mandatory=False, + default_value = "STAT/SDP/1" + ) + # ----- RECV mapping Power_to_RECV_mapping = device_property( @@ -231,6 +246,9 @@ class AntennaField(lofar_device): Antenna_Usage_Mask_R = attribute(doc='Whether each antenna will be used.', dtype=(bool,), max_dim_x=MAX_NUMBER_OF_HBAT) + Antenna_to_SDP_Mapping_R = attribute(doc='To which (fpga, input) pair each antenna is connected. -1=unconnected.', + dtype=((numpy.int32,),), max_dim_x=2, max_dim_y=MAX_NUMBER_OF_HBAT) + 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) @@ -302,6 +320,9 @@ class AntennaField(lofar_device): return numpy.logical_or(antennas_forced_on, antennas_auto_on) + def read_Antenna_to_SDP_Mapping_R(self): + return self.Antenna_to_SDP_Mapping.reshape(-1,2) + def read_nr_antennas_R(self): # The number of antennas should be equal to: # * the number of elements in the Control_to_RECV_mapping (after reshaping), @@ -309,6 +330,7 @@ class AntennaField(lofar_device): # * the number of antennas exposed through Antenna_Reference_ITRF_R. # * the number of elements in Antenna_Use # * the number of elements in Antenna_Quality + # * the number of elements in Antenna_to_SDP_Mapping # # Parsing a property here is quickest, so we chose that. return len(self.Control_to_RECV_mapping) // 2 diff --git a/tangostationcontrol/tangostationcontrol/devices/sdp/digitalbeam.py b/tangostationcontrol/tangostationcontrol/devices/sdp/digitalbeam.py index a310eb5e44b10ac5b4f08048bd0a0850896fb3a2..89ebcf4ec38570d8ec55a512240614405195e20a 100644 --- a/tangostationcontrol/tangostationcontrol/devices/sdp/digitalbeam.py +++ b/tangostationcontrol/tangostationcontrol/devices/sdp/digitalbeam.py @@ -64,13 +64,6 @@ class DigitalBeam(beam_device): default_value = "STAT/Beamlet/1" ) - Input_to_Antenna_Mapping = device_property( - dtype=(numpy.int32,), - doc='Which antenna of the antennafield is connected to each input. -1 if no antenna is present.', - mandatory=False, - default_value = [-1] * MAX_INPUTS - ) - # ---------- # Attributes # ---------- @@ -90,7 +83,7 @@ class DigitalBeam(beam_device): def nr_inputs(self): """ Return the number of configured inputs. """ - return max(self.Input_to_Antenna_Mapping) + 1 + return len(self.antennafield_proxy.Antenna_to_SDP_Mapping_R) def read_input_select_RW(self): return self._input_select @@ -100,11 +93,12 @@ class DigitalBeam(beam_device): def read_antenna_select_RW(self): # select only the rows from self.__input_select for which a mapping onto antennas is defined. - antenna_select = [[False] * self.NUM_BEAMLETS] * self.nr_inputs() + antenna_to_sdp_mapping = self.antennafield_proxy.Antenna_to_SDP_Mapping_R + antenna_select = [[False] * self.NUM_BEAMLETS] * len(antenna_to_sdp_mapping) - for input_nr, antenna_nr in enumerate(self.Input_to_Antenna_Mapping): - if antenna_nr >= 0: - antenna_select[antenna_nr] = self._input_select[input_nr] + for antenna_nr, (fpga_nr, input_nr) in enumerate(antenna_to_sdp_mapping): + if input_nr >= 0: + antenna_select[antenna_nr] = self._input_select[fpga_nr * 6 + input_nr] return antenna_select @@ -113,14 +107,14 @@ class DigitalBeam(beam_device): # to select the antennas they would like to use. antenna_usage_mask = self.antennafield_proxy.Antenna_Usage_Mask_R - for input_nr, antenna_nr in enumerate(self.Input_to_Antenna_Mapping): - if antenna_nr >= 0: + for antenna_nr, (fpga_nr, input_nr) in enumerate(self.antennafield_proxy.Antenna_to_SDP_Mapping_R): + if input_nr >= 0: if antenna_usage_mask[antenna_nr]: # use antenna for the beamlets as supplied by the client - self._input_select[input_nr] = antennas[antenna_nr] + self._input_select[fpga_nr * 6 + input_nr] = antennas[antenna_nr] else: # do not use antenna for any beamlet - self._input_select[input_nr] = False + self._input_select[fpga_nr * 6 + input_nr] = False # ---------- # Summarising Attributes @@ -151,9 +145,9 @@ class DigitalBeam(beam_device): # Generate positions for all FPGA inputs. # Use reference position for any missing antennas so they always get a delay of 0 input_itrf = numpy.array([reference_itrf] * self.MAX_INPUTS) - for input_nr, antenna_nr in enumerate(self.Input_to_Antenna_Mapping): - if antenna_nr >= 0: - input_itrf[input_nr] = antenna_itrf[antenna_nr] + for antenna_nr, (fpga_nr, input_nr) in enumerate(self.antennafield_proxy.Antenna_to_SDP_Mapping_R): + if input_nr >= 0: + input_itrf[fpga_nr * 6 + input_nr] = antenna_itrf[antenna_nr] # a delay calculator self.delay_calculator = Delays(reference_itrf) diff --git a/tangostationcontrol/tangostationcontrol/integration_test/default/devices/test_device_observation.py b/tangostationcontrol/tangostationcontrol/integration_test/default/devices/test_device_observation.py index 8a4a2b1c65323a83f216c386130de66eb903f07e..fb931b7dc60ed0478565618c1e289834ba783dc7 100644 --- a/tangostationcontrol/tangostationcontrol/integration_test/default/devices/test_device_observation.py +++ b/tangostationcontrol/tangostationcontrol/integration_test/default/devices/test_device_observation.py @@ -22,24 +22,16 @@ class TestDeviceObservation(AbstractTestBases.TestDeviceBase): NUM_TILES = 48 NUM_BEAMLETS_CTRL = 488 NUM_INPUTS = 96 - INPUT_TO_ANTENNA_MAPPING = [ - "0", "1", "2", "3", "4", "5", - "6", "7", "8", "9", "10", "11", - "12", "13", "14", "15", "16", "17", - "18", "19", "20", "21", "22", "23", - "24", "25", "26", "27", "28", "29", - "30", "31", "32", "33", "34", "35", - "36", "37", "38", "39", "40", "41", - "42", "43", "44", "45", "46", "47", - "-1", "-1", "-1", "-1", "-1", "-1", - "-1", "-1", "-1", "-1", "-1", "-1", - "-1", "-1", "-1", "-1", "-1", "-1", - "-1", "-1", "-1", "-1", "-1", "-1", - "-1", "-1", "-1", "-1", "-1", "-1", - "-1", "-1", "-1", "-1", "-1", "-1", - "-1", "-1", "-1", "-1", "-1", "-1", - "-1", "-1", "-1", "-1", "-1", "-1" - ] + ANTENNA_TO_SDP_MAPPING = [ + "0", "0", "0", "1", "0", "2", "0", "3", "0", "4", "0", "5", + "1", "0", "1", "1", "1", "2", "1", "3", "1", "4", "1", "5", + "2", "0", "2", "1", "2", "2", "2", "3", "2", "4", "2", "5", + "3", "0", "3", "1", "3", "2", "3", "3", "3", "4", "3", "5", + "4", "0", "4", "1", "4", "2", "4", "3", "4", "4", "4", "5", + "5", "0", "5", "1", "5", "2", "5", "3", "5", "4", "5", "5", + "6", "0", "6", "1", "6", "2", "6", "3", "6", "4", "6", "5", + "7", "0", "7", "1", "7", "2", "7", "3", "7", "4", "7", "5", + ] def setUp(self): super().setUp("STAT/Observation/1") @@ -74,6 +66,7 @@ class TestDeviceObservation(AbstractTestBases.TestDeviceBase): antenna_use = numpy.array([AntennaUse.AUTO] * 96) antennafield_proxy.put_property({"RECV_devices": ["STAT/RECV/1"], "Control_to_RECV_mapping": numpy.array(control_mapping).flatten(), + "Antenna_to_SDP_Mapping": self.ANTENNA_TO_SDP_MAPPING, 'Antenna_Quality': antenna_qualities, 'Antenna_Use': antenna_use}) antennafield_proxy.off() antennafield_proxy.boot() @@ -90,7 +83,6 @@ class TestDeviceObservation(AbstractTestBases.TestDeviceBase): def setup_digitalbeam_proxy(self): # setup Digitalbeam digitalbeam_proxy = TestDeviceProxy("STAT/DigitalBeam/1") - digitalbeam_proxy.put_property({"Input_to_Antenna_Mapping": numpy.array(self.INPUT_TO_ANTENNA_MAPPING).flatten()}) digitalbeam_proxy.off() digitalbeam_proxy.warm_boot() digitalbeam_proxy.set_defaults() diff --git a/tangostationcontrol/tangostationcontrol/integration_test/default/devices/test_device_observation_control.py b/tangostationcontrol/tangostationcontrol/integration_test/default/devices/test_device_observation_control.py index 1e6aff8eff8870e2bc224c9ca3e0c7908363c69f..ac325e0cbcc9f5dd663ce21c104461516819a9cf 100644 --- a/tangostationcontrol/tangostationcontrol/integration_test/default/devices/test_device_observation_control.py +++ b/tangostationcontrol/tangostationcontrol/integration_test/default/devices/test_device_observation_control.py @@ -24,24 +24,16 @@ class TestObservationControlDevice(AbstractTestBases.TestDeviceBase): NUM_TILES = 48 NUM_BEAMLETS_CTRL = 488 NUM_INPUTS = 96 - INPUT_TO_ANTENNA_MAPPING = [ - "0", "1", "2", "3", "4", "5", - "6", "7", "8", "9", "10", "11", - "12", "13", "14", "15", "16", "17", - "18", "19", "20", "21", "22", "23", - "24", "25", "26", "27", "28", "29", - "30", "31", "32", "33", "34", "35", - "36", "37", "38", "39", "40", "41", - "42", "43", "44", "45", "46", "47", - "-1", "-1", "-1", "-1", "-1", "-1", - "-1", "-1", "-1", "-1", "-1", "-1", - "-1", "-1", "-1", "-1", "-1", "-1", - "-1", "-1", "-1", "-1", "-1", "-1", - "-1", "-1", "-1", "-1", "-1", "-1", - "-1", "-1", "-1", "-1", "-1", "-1", - "-1", "-1", "-1", "-1", "-1", "-1", - "-1", "-1", "-1", "-1", "-1", "-1" - ] + ANTENNA_TO_SDP_MAPPING = [ + "0", "0", "0", "1", "0", "2", "0", "3", "0", "4", "0", "5", + "1", "0", "1", "1", "1", "2", "1", "3", "1", "4", "1", "5", + "2", "0", "2", "1", "2", "2", "2", "3", "2", "4", "2", "5", + "3", "0", "3", "1", "3", "2", "3", "3", "3", "4", "3", "5", + "4", "0", "4", "1", "4", "2", "4", "3", "4", "4", "4", "5", + "5", "0", "5", "1", "5", "2", "5", "3", "5", "4", "5", "5", + "6", "0", "6", "1", "6", "2", "6", "3", "6", "4", "6", "5", + "7", "0", "7", "1", "7", "2", "7", "3", "7", "4", "7", "5", + ] def setUp(self): super().setUp("STAT/ObservationControl/1") @@ -73,7 +65,8 @@ class TestObservationControlDevice(AbstractTestBases.TestDeviceBase): antennafield_proxy = TestDeviceProxy("STAT/AntennaField/1") control_mapping = [[1,i] for i in range(self.NUM_TILES)] antennafield_proxy.put_property({"RECV_devices": ["STAT/RECV/1"], - "Power_to_RECV_mapping": numpy.array(control_mapping).flatten()}) + "Power_to_RECV_mapping": numpy.array(control_mapping).flatten(), + "Antenna_to_SDP_Mapping": self.ANTENNA_TO_SDP_MAPPING}) antennafield_proxy.off() antennafield_proxy.warm_boot() antennafield_proxy.set_defaults() @@ -90,7 +83,6 @@ class TestObservationControlDevice(AbstractTestBases.TestDeviceBase): def setup_digitalbeam_proxy(self): # setup Digitalbeam digitalbeam_proxy = TestDeviceProxy("STAT/DigitalBeam/1") - digitalbeam_proxy.put_property({"Input_to_Antenna_Mapping": numpy.array(self.INPUT_TO_ANTENNA_MAPPING).flatten()}) digitalbeam_proxy.off() digitalbeam_proxy.warm_boot() digitalbeam_proxy.set_defaults()