diff --git a/README.md b/README.md index bf330a2d03304448895833c98a4b55588606dd9a..48c5c8a8ddc8ba17c77c3dee35224a9bd117b77d 100644 --- a/README.md +++ b/README.md @@ -115,6 +115,7 @@ Next change the version in the following places: # Release Notes +* 0.21.0 Use radians instead of degrees when interpreting pointings * 0.20.5 Manage both polarisations in RCU_band_select_R(W), Antenna_Loss_R, and Frequency_Band_RW * 0.20.4 Collapse AbstractHierarchyDevice and AbstractHierarchy into one class * 0.20.3 Fix application of Field_Attenuation_R diff --git a/tangostationcontrol/VERSION b/tangostationcontrol/VERSION index 1b619f348236754cc130127b8bf630539ca0930e..885415662ff8cd71c114c96b3cd70daaa329f04b 100644 --- a/tangostationcontrol/VERSION +++ b/tangostationcontrol/VERSION @@ -1 +1 @@ -0.20.5 +0.21.0 diff --git a/tangostationcontrol/integration_test/default/devices/test_device_digitalbeam.py b/tangostationcontrol/integration_test/default/devices/test_device_digitalbeam.py index 4316c829a52e1bd71f8cefe3c6000c62c2140749..a152c5e10a5221959d43f88f8a51099186be9b38 100644 --- a/tangostationcontrol/integration_test/default/devices/test_device_digitalbeam.py +++ b/tangostationcontrol/integration_test/default/devices/test_device_digitalbeam.py @@ -136,7 +136,7 @@ class TestDeviceDigitalBeam(AbstractTestBases.TestDeviceBase): # Point to Zenith self.proxy.set_pointing( numpy.array( - [["AZELGEO", "0deg", "90deg"]] * self.proxy.nr_beamlets_R + [["AZELGEO", "0rad", "1.570796rad"]] * self.proxy.nr_beamlets_R ).flatten() ) @@ -180,7 +180,7 @@ class TestDeviceDigitalBeam(AbstractTestBases.TestDeviceBase): # Point to Zenith self.proxy.set_pointing( numpy.array( - [["AZELGEO", "0deg", "90deg"]] * self.proxy.nr_beamlets_R + [["AZELGEO", "0rad", "1.570796rad"]] * self.proxy.nr_beamlets_R ).flatten() ) # Store values with first subband configuration @@ -228,7 +228,7 @@ class TestDeviceDigitalBeam(AbstractTestBases.TestDeviceBase): self.proxy.set_pointing( numpy.array( - [["AZELGEO", "0deg", "90deg"]] * self.proxy.nr_beamlets_R + [["AZELGEO", "0rad", "1.570796rad"]] * self.proxy.nr_beamlets_R ).flatten() ) diff --git a/tangostationcontrol/integration_test/default/devices/test_device_observation.py b/tangostationcontrol/integration_test/default/devices/test_device_observation.py index b3635044730ea7c36953a46a4563a6ee769cecac..a21df5d396b4f976b66c3bece1796ee3f9ce5009 100644 --- a/tangostationcontrol/integration_test/default/devices/test_device_observation.py +++ b/tangostationcontrol/integration_test/default/devices/test_device_observation.py @@ -225,14 +225,14 @@ class TestDeviceObservation(AbstractTestBases.TestDeviceBase): saps_pointing = [ ( pointing_direction["direction_type"], - f"{pointing_direction['angle1']}deg", - f"{pointing_direction['angle2']}deg", + f"{pointing_direction['angle1']}rad", + f"{pointing_direction['angle2']}rad", ) ] * len(data["SAPs"][0]["subbands"]) tile_beam = [ str(data["tile_beam"]["direction_type"]), - f"{data['tile_beam']['angle1']}deg", - f"{data['tile_beam']['angle2']}deg", + f"{data['tile_beam']['angle1']}rad", + f"{data['tile_beam']['angle2']}rad", ] first_beamlet = data["first_beamlet"] @@ -290,7 +290,7 @@ class TestDeviceObservation(AbstractTestBases.TestDeviceBase): def test_apply_pointing(self): """Test that attribute sap pointing is correctly applied""" digitalbeam_proxy = self.setup_digitalbeam_proxy() - default_pointing = [("AZELGEO", "0deg", "90deg")] * N_beamlets_ctrl + default_pointing = [("AZELGEO", "0rad", "1.570796rad")] * N_beamlets_ctrl digitalbeam_proxy.Pointing_direction_RW = default_pointing self.assertListEqual( list(digitalbeam_proxy.Pointing_direction_RW), default_pointing @@ -299,26 +299,42 @@ class TestDeviceObservation(AbstractTestBases.TestDeviceBase): self.proxy.observation_settings_RW = self.VALID_JSON self.proxy.Initialise() self.proxy.On() - expected_pointing = [("J2000", "1.5deg", "0deg")] * 3 + [ - ("AZELGEO", "0deg", "90deg") + + expected_pointing = [("J2000", "0.0261799rad", "0rad")] * 3 + [ + ("AZELGEO", "0rad", "1.570796rad") + ] * (N_beamlets_ctrl - 3) + + digitalbeam_pointing = list(digitalbeam_proxy.Pointing_direction_RW[0]) + digitalbeam_pointing[1] = digitalbeam_pointing[1][:9] + "rad" + digitalbeam_pointing = [tuple(digitalbeam_pointing)] * 3 + [ + ("AZELGEO", "0rad", "1.570796rad") ] * (N_beamlets_ctrl - 3) + + self.maxDiff = None + self.assertListEqual( - list(digitalbeam_proxy.Pointing_direction_RW), expected_pointing + digitalbeam_pointing, + expected_pointing, ) def test_apply_tilebeam(self): # failing """Test that attribute tilebeam is correctly applied""" tilebeam_proxy = self.setup_tilebeam_proxy() - pointing_direction = [("J2000", "0deg", "0deg")] * CS001_TILES + pointing_direction = [("J2000", "0rad", "0rad")] * CS001_TILES tilebeam_proxy.Pointing_direction_RW = pointing_direction self.assertListEqual( - list(tilebeam_proxy.Pointing_direction_RW[0]), ["J2000", "0deg", "0deg"] + list(tilebeam_proxy.Pointing_direction_RW[0]), ["J2000", "0rad", "0rad"] ) self.proxy.off() self.proxy.observation_settings_RW = self.VALID_JSON self.proxy.Initialise() self.proxy.On() + + tilebeam_directions = list(tilebeam_proxy.Pointing_direction_RW[0]) + tilebeam_directions[1] = tilebeam_directions[1][:9] + "rad" + self.assertListEqual( - list(tilebeam_proxy.Pointing_direction_RW[0]), ["J2000", "1.5deg", "0deg"] + tilebeam_directions, + ["J2000", "0.0261799rad", "0rad"], ) diff --git a/tangostationcontrol/integration_test/default/devices/test_device_tilebeam.py b/tangostationcontrol/integration_test/default/devices/test_device_tilebeam.py index 2fc4edc793fe9e317fbe14e4e856e6f65239e25f..5d644bb06336c3757a0380cc2534ead782781ab4 100644 --- a/tangostationcontrol/integration_test/default/devices/test_device_tilebeam.py +++ b/tangostationcontrol/integration_test/default/devices/test_device_tilebeam.py @@ -28,7 +28,7 @@ class NumpyEncoder(json.JSONEncoder): class TestDeviceTileBeam(AbstractTestBases.TestDeviceBase): POINTING_DIRECTION = numpy.array( - [["J2000", "0deg", "0deg"]] * CS001_TILES + [["J2000", "0rad", "0rad"]] * CS001_TILES ).flatten() def setUp(self): @@ -124,7 +124,7 @@ class TestDeviceTileBeam(AbstractTestBases.TestDeviceBase): # Point to Zenith self.proxy.set_pointing( - numpy.array([["AZELGEO", "0deg", "90deg"]] * CS001_TILES).flatten() + numpy.array([["AZELGEO", "0rad", "1.570796rad"]] * CS001_TILES).flatten() ) calculated_HBAT_delay_steps = numpy.array( @@ -149,7 +149,7 @@ class TestDeviceTileBeam(AbstractTestBases.TestDeviceBase): self.proxy.Tracking_enabled_RW = False # point at north on the horizon - self.proxy.set_pointing(["AZELGEO", "0deg", "0deg"] * CS001_TILES) + self.proxy.set_pointing(["AZELGEO", "0rad", "0rad"] * CS001_TILES) # obtain delays of the X polarisation of all the elements of the first tile north_beam_delay_steps = antennafield_proxy.HBAT_BF_delay_steps_RW[0].reshape( @@ -161,17 +161,19 @@ class TestDeviceTileBeam(AbstractTestBases.TestDeviceBase): north_beam_delay_steps.tolist(), numpy.rot90(north_beam_delay_steps).tolist(), ) - - for angle in (90, 180, 270): + # 90, 180 and 270 degrees + for angle in (1.570796, 3.141593, 4.712389): # point at angle degrees (90=E, 180=S, 270=W) - self.proxy.set_pointing(["AZELGEO", f"{angle}deg", "0deg"] * CS001_TILES) + self.proxy.set_pointing(["AZELGEO", f"{angle}rad", "0rad"] * CS001_TILES) # obtain delays of the X polarisation of all the elements of the first tile angled_beam_delay_steps = antennafield_proxy.HBAT_BF_delay_steps_RW[ 0 ].reshape(4, 4, 2)[:, :, 0] - expected_delay_steps = numpy.rot90(north_beam_delay_steps, k=-(angle / 90)) + expected_delay_steps = numpy.rot90( + north_beam_delay_steps, k=-(int((angle * 180) / numpy.pi) / 90) + ) self.assertListEqual( expected_delay_steps.tolist(), @@ -234,7 +236,7 @@ class TestDeviceTileBeam(AbstractTestBases.TestDeviceBase): self.assertTrue(self.proxy.Tracking_enabled_R) # point somewhere - new_pointings = [("J2000", f"{tile}deg", "0deg") for tile in range(CS001_TILES)] + new_pointings = [("J2000", f"{tile}rad", "0rad") for tile in range(CS001_TILES)] self.proxy.Pointing_direction_RW = new_pointings # check pointing diff --git a/tangostationcontrol/integration_test/digitalbeam_performance/test_digitalbeam_performance.py b/tangostationcontrol/integration_test/digitalbeam_performance/test_digitalbeam_performance.py index d2680a02f2014f78cd084ad3a187fceb37cea568..4ed1e4e4aa2cd2fc6854b11724c73a7d647daab8 100644 --- a/tangostationcontrol/integration_test/digitalbeam_performance/test_digitalbeam_performance.py +++ b/tangostationcontrol/integration_test/digitalbeam_performance/test_digitalbeam_performance.py @@ -21,7 +21,7 @@ logger = logging.getLogger() class TestDigitalbeamPerformance(base.IntegrationTestCase): # The AntennaField is setup with self.NR_TILES tiles in the test configuration POINTING_DIRECTION = numpy.array( - [["J2000", "0deg", "0deg"]] * N_beamlets_ctrl + [["J2000", "0rad", "0rad"]] * N_beamlets_ctrl ).flatten() def setUp(self): diff --git a/tangostationcontrol/integration_test/tilebeam_performance/test_tilebeam_performance.py b/tangostationcontrol/integration_test/tilebeam_performance/test_tilebeam_performance.py index 916ee37a84349723f584abd914eb4e1bf50ce04d..f1dca1038003eeebedaa1fcec2a5f67405d47a97 100644 --- a/tangostationcontrol/integration_test/tilebeam_performance/test_tilebeam_performance.py +++ b/tangostationcontrol/integration_test/tilebeam_performance/test_tilebeam_performance.py @@ -19,7 +19,7 @@ logger = logging.getLogger() class TestTilebeamPerformance(base.IntegrationTestCase): # The AntennaField is setup with self.NR_TILES tiles in the test configuration NR_TILES = 48 - POINTING_DIRECTION = numpy.array([["J2000", "0deg", "0deg"]] * NR_TILES).flatten() + POINTING_DIRECTION = numpy.array([["J2000", "0rad", "0rad"]] * NR_TILES).flatten() def setUp(self): super(TestTilebeamPerformance, self).setUp() diff --git a/tangostationcontrol/tangostationcontrol/devices/base_device_classes/beam_device.py b/tangostationcontrol/tangostationcontrol/devices/base_device_classes/beam_device.py index 7a19a17fabe9b858bbd6b39a64fe6556f1875de0..b7b370aa550a8116edb53dc87dba59b50ae38bef 100644 --- a/tangostationcontrol/tangostationcontrol/devices/base_device_classes/beam_device.py +++ b/tangostationcontrol/tangostationcontrol/devices/base_device_classes/beam_device.py @@ -299,7 +299,7 @@ class BeamDevice(AsyncDevice): (num_pointings, N_point_prop), dtype="<U32" ) self._beam_manager.new_pointing_direction = numpy.array( - [["AZELGEO", "0deg", "90deg"]] * num_pointings, dtype="<U32" + [["AZELGEO", "0rad", "1.570796rad"]] * num_pointings, dtype="<U32" ) self._beam_manager.beam_tracking_application_offset = ( diff --git a/tangostationcontrol/tangostationcontrol/devices/observation.py b/tangostationcontrol/tangostationcontrol/devices/observation.py index 471f0a1fc8b026cdb28343564f8ccd97e9f14be2..d195f5480962ebfe5469f35e81f9a25c617e0a21 100644 --- a/tangostationcontrol/tangostationcontrol/devices/observation.py +++ b/tangostationcontrol/tangostationcontrol/devices/observation.py @@ -141,8 +141,8 @@ class Observation(LOFARDevice): saps_pointing.append( ( sap.pointing.direction_type, - f"{sap.pointing.angle1}deg", - f"{sap.pointing.angle2}deg", + f"{sap.pointing.angle1}rad", + f"{sap.pointing.angle2}rad", ), ) return saps_pointing @@ -159,8 +159,8 @@ class Observation(LOFARDevice): pointing_direction = self._observation_settings.tile_beam return [ str(pointing_direction.direction_type), - f"{pointing_direction.angle1}deg", - f"{pointing_direction.angle2}deg", + f"{pointing_direction.angle1}rad", + f"{pointing_direction.angle2}rad", ] @attribute( @@ -309,7 +309,6 @@ class Observation(LOFARDevice): @log_exceptions() def _stop_observation(self): """Tear down station resources we used.""" - pass @fault_on_error() diff --git a/tangostationcontrol/tangostationcontrol/test/devices/test_observation_base.py b/tangostationcontrol/tangostationcontrol/test/devices/test_observation_base.py index b1f20f80b5aed64079bb60b63b5ec21d22b25ae8..03dc58103d247e26978d36bea41fa0e3ca8bde9e 100644 --- a/tangostationcontrol/tangostationcontrol/test/devices/test_observation_base.py +++ b/tangostationcontrol/tangostationcontrol/test/devices/test_observation_base.py @@ -13,11 +13,11 @@ class TestObservationBase: "SAPs": [{ "subbands": [10, 20, 30], "pointing": { - "angle1": 1.5, "angle2": 0, "direction_type": "J2000" + "angle1": 0.0261799, "angle2": 0, "direction_type": "J2000" } }], "tile_beam": - { "angle1": 1.5, "angle2": 0, "direction_type": "J2000" }, + { "angle1": 0.0261799, "angle2": 0, "direction_type": "J2000" }, "first_beamlet": 0 } """ diff --git a/tangostationcontrol/test/beam/test_delays.py b/tangostationcontrol/test/beam/test_delays.py index 683a96c730493a4a1542687aa60c76abc91f35e3..7d4173c6fdf49d58abda959509d4fbfc70d5efcb 100644 --- a/tangostationcontrol/test/beam/test_delays.py +++ b/tangostationcontrol/test/beam/test_delays.py @@ -41,11 +41,11 @@ class TestDelays(base.TestCase): d = Delays([0, 0, 0]) # should accept base use cases - self.assertTrue(d.is_valid_direction(("J2000", "0deg", "0deg"))) - self.assertTrue(d.is_valid_direction(("J2000", "270deg", "90deg"))) - self.assertTrue(d.is_valid_direction(("AZELGEO", "0deg", "0deg"))) - self.assertTrue(d.is_valid_direction(("AZELGEO", "270deg", "90deg"))) - self.assertTrue(d.is_valid_direction(("SUN", "0deg", "0deg"))) + self.assertTrue(d.is_valid_direction(("J2000", "0rad", "0rad"))) + self.assertTrue(d.is_valid_direction(("J2000", "4.712389rad", "1.570796rad"))) + self.assertTrue(d.is_valid_direction(("AZELGEO", "0rad", "0rad"))) + self.assertTrue(d.is_valid_direction(("AZELGEO", "4.712389rad", "1.570796rad"))) + self.assertTrue(d.is_valid_direction(("SUN", "0rad", "0rad"))) # i dont get these either, but casacore accepts them self.assertTrue(d.is_valid_direction([])) @@ -54,16 +54,16 @@ class TestDelays(base.TestCase): d.is_valid_direction( ( "J2000", - "0deg", + "0rad", ) ) ) - self.assertTrue(d.is_valid_direction(("J2000", "0deg", "0deg", "0deg"))) + self.assertTrue(d.is_valid_direction(("J2000", "0rad", "0rad", "0rad"))) # should not throw, and return False, on bad uses self.assertFalse(d.is_valid_direction(("", "", ""))) self.assertFalse( - d.is_valid_direction(("J2000", "0deg", "0deg", "0deg", "0deg")) + d.is_valid_direction(("J2000", "0rad", "0rad", "0rad", "0rad")) ) self.assertFalse(d.is_valid_direction((1, 2, 3))) self.assertFalse(d.is_valid_direction("foo")) @@ -80,7 +80,7 @@ class TestDelays(base.TestCase): d.set_measure_time(timestamp) # point to the sun - direction = "SUN", "0deg", "0deg" + direction = "SUN", "0rad", "0rad" # calculate the delays based on the set reference position, the set time and now the set direction and antenna positions. pointing = d.measure.direction(*direction) @@ -121,7 +121,7 @@ class TestDelays(base.TestCase): # compute the delays for an antennas w.r.t. the reference position # # obtain the direction vector for a specific pointing - direction = "J2000", "0deg", "0deg" + direction = "J2000", "0rad", "0rad" # calculate the delays based on the set reference position, the set time and now the set direction and antenna positions. delays = d.delays(direction, antenna_itrf) @@ -146,7 +146,7 @@ class TestDelays(base.TestCase): d.set_measure_time(timestamp) # # obtain the direction vector for a specific pointing - direction = "J2000", "0deg", "90deg" + direction = "J2000", "0rad", "1.570796rad" # calculate the delays based on the set reference position, the set time and now the set direction and antenna positions. delays = d.delays(direction, antenna_itrf) @@ -176,7 +176,7 @@ class TestDelays(base.TestCase): 2022, 3, 1, 0, 0, 0 ) # timestamp does not actually matter, but casacore doesn't know that. d.set_measure_time(timestamp) - direction = "J2000", "0deg", "90deg" + direction = "J2000", "0rad", "1.570796rad" # calculate the delays based on the set reference position, the set time and now the set direction and antenna positions. delays = d.delays(direction, antenna_itrf) @@ -192,7 +192,12 @@ class TestDelays(base.TestCase): # generate different positions and directions positions = numpy.array([[i, 2, 3] for i in range(5)]) - directions = numpy.array([["J2000", f"{i}deg", f"{i}deg"] for i in range(90)]) + directions = numpy.array( + [ + ["J2000", f"{i*numpy.pi/180}rad", f"{i*numpy.pi/180}rad"] + for i in range(90) + ] + ) bulk_result = d.delays_bulk(directions, positions) @@ -218,7 +223,7 @@ class TestDelays(base.TestCase): d.set_measure_time(timestamp) positions = numpy.array([[1, 2, 3]] * MAX_ANTENNA) - directions = numpy.array([["J2000", "0deg", "0deg"]] * N_beamlets_ctrl) + directions = numpy.array([["J2000", "0rad", "0rad"]] * N_beamlets_ctrl) count = 10 before = time.monotonic_ns() diff --git a/tangostationcontrol/test/devices/sdp/test_digitalbeam_device.py b/tangostationcontrol/test/devices/sdp/test_digitalbeam_device.py index 4088b766487845714d25382a71774c09e7f2928d..381b60fb79cf46aec7add7191f87383a843e583e 100644 --- a/tangostationcontrol/test/devices/sdp/test_digitalbeam_device.py +++ b/tangostationcontrol/test/devices/sdp/test_digitalbeam_device.py @@ -41,7 +41,7 @@ class TestDigitalBeamDevice(device_base.DeviceTestCase): """Verify won't overwrite digitalbeam data if no input_selected""" input_data = numpy.array( - [["AZELGEO", "0deg", "90deg"]] * N_beamlets_ctrl + [["AZELGEO", "0rad", "1.570796rad"]] * N_beamlets_ctrl ).flatten() current_data = numpy.array([[16384] * (A_pn * N_beamlets_ctrl)] * N_pn) @@ -81,7 +81,7 @@ class TestDigitalBeamDevice(device_base.DeviceTestCase): """Verify can overwrite digitalbeam data if input_selected""" input_data = numpy.array( - [["AZELGEO", "0deg", "90deg"]] * N_beamlets_ctrl + [["AZELGEO", "0rad", "1.570796rad"]] * N_beamlets_ctrl ).flatten() current_data = numpy.array([[16384] * (A_pn * N_beamlets_ctrl)] * N_pn)