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

L2SS-433: Add beamlet device, which takes over responsibility of all beamlet...

L2SS-433: Add beamlet device, which takes over responsibility of all beamlet and bf_weight attributes from SDP
parent 4136c11d
Branches
Tags
1 merge request!262L2SS-433: Add beamlet device
Showing
with 452 additions and 53 deletions
...@@ -97,6 +97,8 @@ docker_build_image_all: ...@@ -97,6 +97,8 @@ docker_build_image_all:
- bash $CI_PROJECT_DIR/sbin/tag_and_push_docker_image.sh unb2-sim latest - bash $CI_PROJECT_DIR/sbin/tag_and_push_docker_image.sh unb2-sim latest
- bash $CI_PROJECT_DIR/sbin/tag_and_push_docker_image.sh device-apsct latest - bash $CI_PROJECT_DIR/sbin/tag_and_push_docker_image.sh device-apsct latest
- bash $CI_PROJECT_DIR/sbin/tag_and_push_docker_image.sh device-apspu latest - bash $CI_PROJECT_DIR/sbin/tag_and_push_docker_image.sh device-apspu latest
- bash $CI_PROJECT_DIR/sbin/tag_and_push_docker_image.sh device-beam latest
- bash $CI_PROJECT_DIR/sbin/tag_and_push_docker_image.sh device-beamlet latest
- bash $CI_PROJECT_DIR/sbin/tag_and_push_docker_image.sh device-boot latest - bash $CI_PROJECT_DIR/sbin/tag_and_push_docker_image.sh device-boot latest
- bash $CI_PROJECT_DIR/sbin/tag_and_push_docker_image.sh device-docker latest - bash $CI_PROJECT_DIR/sbin/tag_and_push_docker_image.sh device-docker latest
- bash $CI_PROJECT_DIR/sbin/tag_and_push_docker_image.sh device-observation_control latest - bash $CI_PROJECT_DIR/sbin/tag_and_push_docker_image.sh device-observation_control latest
...@@ -250,6 +252,28 @@ docker_build_image_device_apspu: ...@@ -250,6 +252,28 @@ docker_build_image_device_apspu:
script: script:
# Do not remove 'bash' or statement will be ignored by primitive docker shell # Do not remove 'bash' or statement will be ignored by primitive docker shell
- bash $CI_PROJECT_DIR/sbin/tag_and_push_docker_image.sh device-apspu $tag - bash $CI_PROJECT_DIR/sbin/tag_and_push_docker_image.sh device-apspu $tag
docker_build_image_device_beam:
extends: .base_docker_images_except
only:
refs:
- merge_requests
changes:
- docker-compose/device-beam.yml
- docker-compose/lofar-device-base/*
script:
# Do not remove 'bash' or statement will be ignored by primitive docker shell
- bash $CI_PROJECT_DIR/sbin/tag_and_push_docker_image.sh device-beam $tag
docker_build_image_device_beamlet:
extends: .base_docker_images_except
only:
refs:
- merge_requests
changes:
- docker-compose/device-beamlet.yml
- docker-compose/lofar-device-base/*
script:
# Do not remove 'bash' or statement will be ignored by primitive docker shell
- bash $CI_PROJECT_DIR/sbin/tag_and_push_docker_image.sh device-beamlet $tag
docker_build_image_device_boot: docker_build_image_device_boot:
extends: .base_docker_images_except extends: .base_docker_images_except
only: only:
......
...@@ -21,6 +21,34 @@ ...@@ -21,6 +21,34 @@
} }
} }
}, },
"Beamlet": {
"STAT": {
"Beamlet": {
"STAT/Beamlet/1": {
"properties": {
"FPGA_beamlet_output_hdr_udp_destination_port_RW_default": [
"10001",
"10001",
"10001",
"10001",
"10001",
"10001",
"10001",
"10001",
"10001",
"10001",
"10001",
"10001",
"10001",
"10001",
"10001",
"10001"
]
}
}
}
}
},
"boot": { "boot": {
"STAT": { "STAT": {
"Boot": { "Boot": {
......
...@@ -51,6 +51,61 @@ ...@@ -51,6 +51,61 @@
} }
} }
}, },
"Beamlet": {
"STAT": {
"Beamlet": {
"STAT/Beamlet/1": {
"properties": {
"OPC_Server_Name": [
"10.99.0.252"
],
"OPC_Server_Port": [
"4840"
],
"OPC_Time_Out": [
"5.0"
],
"FPGA_beamlet_output_hdr_eth_destination_mac_RW_default": [
"0c:c4:7a:c0:30:f1",
"0c:c4:7a:c0:30:f1",
"0c:c4:7a:c0:30:f1",
"0c:c4:7a:c0:30:f1",
"0c:c4:7a:c0:30:f1",
"0c:c4:7a:c0:30:f1",
"0c:c4:7a:c0:30:f1",
"0c:c4:7a:c0:30:f1",
"0c:c4:7a:c0:30:f1",
"0c:c4:7a:c0:30:f1",
"0c:c4:7a:c0:30:f1",
"0c:c4:7a:c0:30:f1",
"0c:c4:7a:c0:30:f1",
"0c:c4:7a:c0:30:f1",
"0c:c4:7a:c0:30:f1",
"0c:c4:7a:c0:30:f1"
],
"FPGA_beamlet_output_hdr_ip_destination_address_RW_default": [
"10.99.250.250",
"10.99.250.250",
"10.99.250.250",
"10.99.250.250",
"10.99.250.250",
"10.99.250.250",
"10.99.250.250",
"10.99.250.250",
"10.99.250.250",
"10.99.250.250",
"10.99.250.250",
"10.99.250.250",
"10.99.250.250",
"10.99.250.250",
"10.99.250.250",
"10.99.250.250"
]
}
}
}
}
},
"RECV": { "RECV": {
"STAT": { "STAT": {
"RECV": { "RECV": {
......
...@@ -13,6 +13,61 @@ ...@@ -13,6 +13,61 @@
} }
} }
}, },
"Beamlet": {
"STAT": {
"Beamlet": {
"STAT/Beamlet/1": {
"properties": {
"OPC_Server_Name": [
"dop369.astron.nl"
],
"OPC_Server_Port": [
"4840"
],
"OPC_Time_Out": [
"5.0"
],
"FPGA_beamlet_output_hdr_eth_destination_mac_RW_default": [
"00:07:43:06:c7:00",
"00:07:43:06:c7:00",
"00:07:43:06:c7:00",
"00:07:43:06:c7:00",
"00:07:43:06:c7:00",
"00:07:43:06:c7:00",
"00:07:43:06:c7:00",
"00:07:43:06:c7:00",
"00:07:43:06:c7:00",
"00:07:43:06:c7:00",
"00:07:43:06:c7:00",
"00:07:43:06:c7:00",
"00:07:43:06:c7:00",
"00:07:43:06:c7:00",
"00:07:43:06:c7:00",
"00:07:43:06:c7:00"
],
"FPGA_beamlet_output_hdr_ip_destination_address_RW_default": [
"192.168.0.254",
"192.168.0.254",
"192.168.0.254",
"192.168.0.254",
"192.168.0.254",
"192.168.0.254",
"192.168.0.254",
"192.168.0.254",
"192.168.0.254",
"192.168.0.254",
"192.168.0.254",
"192.168.0.254",
"192.168.0.254",
"192.168.0.254",
"192.168.0.254",
"192.168.0.254"
]
}
}
}
}
},
"RECV": { "RECV": {
"STAT": { "STAT": {
"RECV": { "RECV": {
......
...@@ -51,6 +51,61 @@ ...@@ -51,6 +51,61 @@
} }
} }
}, },
"Beamlet": {
"STAT": {
"Beamlet": {
"STAT/Beamlet/1": {
"properties": {
"OPC_Server_Name": [
"sdptr-sim"
],
"OPC_Server_Port": [
"4840"
],
"OPC_Time_Out": [
"5.0"
],
"FPGA_beamlet_output_hdr_eth_destination_mac_RW_default": [
"01:23:45:67:89:AB",
"01:23:45:67:89:AB",
"01:23:45:67:89:AB",
"01:23:45:67:89:AB",
"01:23:45:67:89:AB",
"01:23:45:67:89:AB",
"01:23:45:67:89:AB",
"01:23:45:67:89:AB",
"01:23:45:67:89:AB",
"01:23:45:67:89:AB",
"01:23:45:67:89:AB",
"01:23:45:67:89:AB",
"01:23:45:67:89:AB",
"01:23:45:67:89:AB",
"01:23:45:67:89:AB",
"01:23:45:67:89:AB"
],
"FPGA_beamlet_output_hdr_ip_destination_address_RW_default": [
"127.0.0.1",
"127.0.0.1",
"127.0.0.1",
"127.0.0.1",
"127.0.0.1",
"127.0.0.1",
"127.0.0.1",
"127.0.0.1",
"127.0.0.1",
"127.0.0.1",
"127.0.0.1",
"127.0.0.1",
"127.0.0.1",
"127.0.0.1",
"127.0.0.1",
"127.0.0.1"
]
}
}
}
}
},
"RECV": { "RECV": {
"STAT": { "STAT": {
"RECV": { "RECV": {
......
#
# Docker compose file that launches an interactive iTango session.
#
# Connect to the interactive session with 'docker attach itango'.
# Disconnect with the Docker deattach sequence: <CTRL>+<P> <CTRL>+<Q>
#
# Defines:
# - itango: iTango interactive session
#
# Requires:
# - lofar-device-base.yml
#
version: '2'
services:
device-beamlet:
image: device-beamlet
# build explicitly, as docker-compose does not understand a local image
# being shared among services.
build:
context: ..
dockerfile: docker-compose/lofar-device-base/Dockerfile
args:
SOURCE_IMAGE: ${LOCAL_DOCKER_REGISTRY_HOST}/${LOCAL_DOCKER_REGISTRY_USER}/tango-itango:${TANGO_ITANGO_VERSION}
container_name: ${CONTAINER_NAME_PREFIX}device-beamlet
logging:
driver: "json-file"
options:
max-size: "100m"
max-file: "10"
networks:
- control
ports:
- "5712:5712" # unique port for this DS
extra_hosts:
- "host.docker.internal:host-gateway"
volumes:
- ..:/opt/lofar/tango:rw
environment:
- TANGO_HOST=${TANGO_HOST}
working_dir: /opt/lofar/tango
entrypoint:
- bin/start-ds.sh
# configure CORBA to _listen_ on 0:port, but tell others we're _reachable_ through ${HOSTNAME}:port, since CORBA
# can't know about our Docker port forwarding
- l2ss-beamlet Beamlet STAT -v -ORBendPoint giop:tcp:0:5712 -ORBendPointPublish giop:tcp:${HOSTNAME}:5712
restart: unless-stopped
...@@ -8,7 +8,8 @@ xst = DeviceProxy("STAT/XST/1") ...@@ -8,7 +8,8 @@ xst = DeviceProxy("STAT/XST/1")
unb2 = DeviceProxy("STAT/UNB2/1") unb2 = DeviceProxy("STAT/UNB2/1")
boot = DeviceProxy("STAT/Boot/1") boot = DeviceProxy("STAT/Boot/1")
beam = DeviceProxy("STAT/Beam/1") beam = DeviceProxy("STAT/Beam/1")
beamlet = DeviceProxy("STAT/Beamlet/1")
docker = DeviceProxy("STAT/Docker/1") docker = DeviceProxy("STAT/Docker/1")
# Put them in a list in case one wants to iterate # Put them in a list in case one wants to iterate
devices = [apsct, apspu, recv, sdp, sst, xst, unb2, boot, beam, docker] devices = [apsct, apspu, recv, sdp, sst, xst, unb2, boot, beam, beamlet, docker]
...@@ -14,13 +14,13 @@ cd "$LOFAR20_DIR/docker-compose" || exit 1 ...@@ -14,13 +14,13 @@ cd "$LOFAR20_DIR/docker-compose" || exit 1
# Build only the required images, please do not build everything that makes CI # Build only the required images, please do not build everything that makes CI
# take really long to finish, especially grafana / jupyter / prometheus. # take really long to finish, especially grafana / jupyter / prometheus.
# jupyter is physically large > 2.5gb and overlayfs is really slow. # jupyter is physically large > 2.5gb and overlayfs is really slow.
make build device-sdp device-recv device-sst device-unb2 device-xst make build device-sdp device-recv device-sst device-unb2 device-xst device-beamlet device-beam
make build sdptr-sim recv-sim unb2-sim apsct-sim apspu-sim make build sdptr-sim recv-sim unb2-sim apsct-sim apspu-sim
make build databaseds dsconfig elk integration-test make build databaseds dsconfig elk integration-test
make build archiver-timescale hdbppts-cm hdbppts-es make build archiver-timescale hdbppts-cm hdbppts-es
# Start and stop sequence # Start and stop sequence
make stop device-boot device-docker device-apsct device-apspu device-sdp device-recv device-sst device-unb2 device-xst device-beam sdptr-sim recv-sim unb2-sim apsct-sim apspu-sim hdbppts-es hdbppts-cm archiver-timescale make stop device-boot device-docker device-apsct device-apspu device-sdp device-recv device-sst device-unb2 device-xst device-beamlet device-beam sdptr-sim recv-sim unb2-sim apsct-sim apspu-sim hdbppts-es hdbppts-cm archiver-timescale
make start databaseds dsconfig elk make start databaseds dsconfig elk
# Give dsconfig and databaseds time to start # Give dsconfig and databaseds time to start
...@@ -38,7 +38,7 @@ make start sdptr-sim recv-sim unb2-sim apsct-sim apspu-sim ...@@ -38,7 +38,7 @@ make start sdptr-sim recv-sim unb2-sim apsct-sim apspu-sim
# Give the simulators time to start # Give the simulators time to start
sleep 5 sleep 5
make start device-boot device-apsct device-apspu device-sdp device-recv device-sst device-unb2 device-xst device-beam make start device-boot device-apsct device-apspu device-sdp device-recv device-sst device-unb2 device-xst device-beam device-beamlet
# Archive devices -> starting order is important # Archive devices -> starting order is important
make start archiver-timescale hdbppts-cm hdbppts-es make start archiver-timescale hdbppts-cm hdbppts-es
......
Beamlet
====================
The ``beamlet == DeviceProxy("STAT/Beamlet/1")`` device controls the creation and emission of beamlets. Each beamlet is a signal stream characterised by:
- The set of antennas to use as input,
- The pointing towards which to beamform these antennas,
- A single subband (frequency) selected from the PPF.
...@@ -20,6 +20,7 @@ Even without having access to any LOFAR2.0 hardware, you can install the full st ...@@ -20,6 +20,7 @@ Even without having access to any LOFAR2.0 hardware, you can install the full st
interfaces/overview interfaces/overview
devices/using devices/using
devices/beam devices/beam
devices/beamlet
devices/boot devices/boot
devices/docker devices/docker
devices/recv devices/recv
......
...@@ -36,6 +36,7 @@ console_scripts = ...@@ -36,6 +36,7 @@ console_scripts =
l2ss-apsct = tangostationcontrol.devices.apsct:main l2ss-apsct = tangostationcontrol.devices.apsct:main
l2ss-apspu = tangostationcontrol.devices.apspu:main l2ss-apspu = tangostationcontrol.devices.apspu:main
l2ss-beam = tangostationcontrol.devices.beam:main l2ss-beam = tangostationcontrol.devices.beam:main
l2ss-beamlet = tangostationcontrol.devices.sdp.beamlet:main
l2ss-boot = tangostationcontrol.devices.boot:main l2ss-boot = tangostationcontrol.devices.boot:main
l2ss-docker-device = tangostationcontrol.devices.docker_device:main l2ss-docker-device = tangostationcontrol.devices.docker_device:main
l2ss-observation = tangostationcontrol.devices.observation:main l2ss-observation = tangostationcontrol.devices.observation:main
......
...@@ -11,8 +11,9 @@ If a new device is added, it will (likely) need to be referenced in several plac ...@@ -11,8 +11,9 @@ If a new device is added, it will (likely) need to be referenced in several plac
- Adjust `tangostationcontrol/tangostationcontrol/devices/boot.py` to add the device to the station initialisation sequence, - Adjust `tangostationcontrol/tangostationcontrol/devices/boot.py` to add the device to the station initialisation sequence,
- Add to `docker-compose/` to create a YaML file to start the device in a docker container. NOTE: it needs a unique 57xx port assigned, - Add to `docker-compose/` to create a YaML file to start the device in a docker container. NOTE: it needs a unique 57xx port assigned,
- Adjust `tangostationcontrol/setup.cfg` to add an entry point for the device in the package installation, - Adjust `tangostationcontrol/setup.cfg` to add an entry point for the device in the package installation,
- Add to `tangostationcontrol/tangostationcontrol/integration_test/devices/` to add an integration test, - Add to `tangostationcontrol/tangostationcontrol/integration_test/default/devices/` to add an integration test,
- Adjust `sbin/run_integration_test.sh` to have the device started when running the integration tests, - Adjust `sbin/run_integration_test.sh` to have the device started when running the integration tests,
- Adjust `.gitlab-ci.yml` to add the device to the `docker_build_image_all` step and to create a `docker_build_image_device_XXX` step,
- Add to `docs/source/devices/` to mention the device in the end-user documentation. - Add to `docs/source/devices/` to mention the device in the end-user documentation.
- Adjust `docs/source/index.rst` to include the newly created file in `docs/source/devices/`. - Adjust `docs/source/index.rst` to include the newly created file in `docs/source/devices/`.
...@@ -237,10 +237,11 @@ class Boot(lofar_device): ...@@ -237,10 +237,11 @@ class Boot(lofar_device):
"STAT/APSCT/1", "STAT/APSCT/1",
"STAT/RECV/1", # RCUs are input for SDP, so initialise them first "STAT/RECV/1", # RCUs are input for SDP, so initialise them first
"STAT/UNB2/1", # Uniboards host SDP, so initialise them first "STAT/UNB2/1", # Uniboards host SDP, so initialise them first
"STAT/SDP/1", # SDP controls the mask for SST/XST/BST, so initialise it first "STAT/SDP/1", # SDP controls the mask for SST/XST/BST/Beamlet, so initialise it first
"STAT/SST/1", "STAT/SST/1",
"STAT/XST/1", "STAT/XST/1",
"STAT/Beam/1", # Accesses RECV and SDP "STAT/Beamlet/1",
"STAT/Beam/1", # Accesses RECV and Beamlet
], ],
) )
......
# -*- coding: utf-8 -*-
#
# Distributed under the terms of the APACHE license.
# See LICENSE.txt for more info.
""" Beamlet Device Server for LOFAR2.0
"""
# PyTango imports
from tango.server import device_property
from tango import AttrWriteType
# Additional import
from tangostationcontrol.common.entrypoint import entry
from tangostationcontrol.clients.attribute_wrapper import attribute_wrapper
from tangostationcontrol.devices.opcua_device import opcua_device
from tangostationcontrol.devices.sdp.sdp import SDP
import numpy
__all__ = ["Beamlet", "main"]
class Beamlet(opcua_device):
# -----------------
# Device Properties
# -----------------
FPGA_beamlet_output_hdr_eth_destination_mac_RW_default = device_property(
dtype='DevVarStringArray',
mandatory=True
)
FPGA_beamlet_output_hdr_ip_destination_address_RW_default = device_property(
dtype='DevVarStringArray',
mandatory=True
)
FPGA_beamlet_output_hdr_udp_destination_port_RW_default = device_property(
dtype='DevVarUShortArray',
mandatory=True
)
FPGA_beamlet_output_enable_RW_default = device_property(
dtype='DevVarBooleanArray',
mandatory=False,
default_value=[False] * 16
)
FPGA_beamlet_output_scale_RW_default = device_property(
dtype='DevVarDoubleArray',
mandatory=False,
default_value=[1.0] * 16
)
first_default_settings = [
'FPGA_beamlet_output_hdr_eth_destination_mac_RW',
'FPGA_beamlet_output_hdr_ip_destination_address_RW',
'FPGA_beamlet_output_hdr_udp_destination_port_RW',
'FPGA_beamlet_output_enable_RW'
]
# ----------
# Attributes
# ----------
FPGA_beamlet_output_enable_R = attribute_wrapper(comms_annotation=["FPGA_beamlet_output_enable_R"], datatype=numpy.bool_, dims=(16,))
FPGA_beamlet_output_enable_RW = attribute_wrapper(comms_annotation=["FPGA_beamlet_output_enable_RW"], datatype=numpy.bool_, dims=(16,), access=AttrWriteType.READ_WRITE)
FPGA_beamlet_output_hdr_eth_destination_mac_R = attribute_wrapper(comms_annotation=["FPGA_beamlet_output_hdr_eth_destination_mac_R"], datatype=numpy.str, dims=(16,))
FPGA_beamlet_output_hdr_eth_destination_mac_RW = attribute_wrapper(comms_annotation=["FPGA_beamlet_output_hdr_eth_destination_mac_RW"], datatype=numpy.str, dims=(16,), access=AttrWriteType.READ_WRITE)
FPGA_beamlet_output_hdr_ip_destination_address_R = attribute_wrapper(comms_annotation=["FPGA_beamlet_output_hdr_ip_destination_address_R"], datatype=numpy.str, dims=(16,))
FPGA_beamlet_output_hdr_ip_destination_address_RW = attribute_wrapper(comms_annotation=["FPGA_beamlet_output_hdr_ip_destination_address_RW"], datatype=numpy.str, dims=(16,), access=AttrWriteType.READ_WRITE)
FPGA_beamlet_output_hdr_udp_destination_port_R = attribute_wrapper(comms_annotation=["FPGA_beamlet_output_hdr_udp_destination_port_R"], datatype=numpy.uint16, dims=(16,))
FPGA_beamlet_output_hdr_udp_destination_port_RW = attribute_wrapper(comms_annotation=["FPGA_beamlet_output_hdr_udp_destination_port_RW"], datatype=numpy.uint16, dims=(16,), access=AttrWriteType.READ_WRITE)
FPGA_beamlet_output_scale_R = attribute_wrapper(comms_annotation=["FPGA_beamlet_output_scale_R"], datatype=numpy.double, dims=(16,))
FPGA_beamlet_output_scale_RW = attribute_wrapper(comms_annotation=["FPGA_beamlet_output_scale_RW"], datatype=numpy.double, dims=(16,), access=AttrWriteType.READ_WRITE)
# List of OPC-UA CP for BF beamlets
S_pn = SDP.S_pn
N_pn = SDP.N_pn
A_pn = 6
N_pol = 2
N_beamlets_ctrl = 488
N_pol_bf = 2
# cint16[N_pn][A_pn][N_pol][N_beamlets_ctrl]
# Co-polarization BF weights. The N_pol = 2 parameter index is:
# 0 for antenna polarization X in beamlet polarization X,
# 1 for antenna polarization Y in beamlet polarization Y.
FPGA_bf_weights_xx_yy_R = attribute_wrapper(comms_annotation=["FPGA_bf_weights_xx_yy_R"], datatype=numpy.int16, dims=(A_pn * N_pol * N_beamlets_ctrl, N_pn))
FPGA_bf_weights_xx_yy_RW = attribute_wrapper(comms_annotation=["FPGA_bf_weights_xx_yy_RW"], datatype=numpy.int16, dims=(A_pn * N_pol * N_beamlets_ctrl, N_pn), access=AttrWriteType.READ_WRITE)
# cint16[N_pn][A_pn][N_pol][N_beamlets_ctrl]
# Cross-polarization BF weights. The N_pol = 2 parameter index is (note that index pol in range 0:N_pol-1 is the antenna polarization, so index !pol is the beamlet polarization):
# 0 for antenna polarization X in beamlet polarization Y,
# 1 for antenna polarization Y in beamlet polarization X.
FPGA_bf_weights_xy_yx_R = attribute_wrapper(comms_annotation=["FPGA_bf_weights_xy_yx_R"], datatype=numpy.int16, dims=(A_pn * N_pol * N_beamlets_ctrl, N_pn))
FPGA_bf_weights_xy_yx_RW = attribute_wrapper(comms_annotation=["FPGA_bf_weights_xy_yx_RW"], datatype=numpy.int16, dims=(A_pn * N_pol * N_beamlets_ctrl, N_pn), access=AttrWriteType.READ_WRITE)
# cint16[N_pn][N_pol_bf][A_pn][N_pol][N_beamlets_ctrl]
# Full Jones matrix of BF weights.
FPGA_bf_weights_xx_xy_yx_yy_R = attribute_wrapper(comms_annotation=["FPGA_bf_weights_xx_xy_yx_yy_R"], datatype=numpy.int16, dims=(N_pol_bf * A_pn * N_pol * N_beamlets_ctrl, N_pn))
FPGA_bf_weights_xx_xy_yx_yy_RW = attribute_wrapper(comms_annotation=["FPGA_bf_weights_xx_xy_yx_yy_RW"], datatype=numpy.int16, dims=(N_pol_bf * A_pn * N_pol * N_beamlets_ctrl, N_pn), access=AttrWriteType.READ_WRITE)
# cint16[N_pn][A_pn][N_beamlets_ctrl]
# BF weights for separate access to respectively w_xx, w_xy, w_yx, and w_yy.
FPGA_bf_weights_xx_R = attribute_wrapper(comms_annotation=["FPGA_bf_weights_xx_R"], datatype=numpy.int16, dims=(A_pn * N_beamlets_ctrl, N_pn))
FPGA_bf_weights_xx_RW = attribute_wrapper(comms_annotation=["FPGA_bf_weights_xx_RW"], datatype=numpy.int16, dims=(A_pn * N_beamlets_ctrl, N_pn), access=AttrWriteType.READ_WRITE)
FPGA_bf_weights_xy_R = attribute_wrapper(comms_annotation=["FPGA_bf_weights_xy_R"], datatype=numpy.int16, dims=(A_pn * N_beamlets_ctrl, N_pn))
FPGA_bf_weights_xy_RW = attribute_wrapper(comms_annotation=["FPGA_bf_weights_xy_RW"], datatype=numpy.int16, dims=(A_pn * N_beamlets_ctrl, N_pn), access=AttrWriteType.READ_WRITE)
FPGA_bf_weights_yx_R = attribute_wrapper(comms_annotation=["FPGA_bf_weights_yx_R"], datatype=numpy.int16, dims=(A_pn * N_beamlets_ctrl, N_pn))
FPGA_bf_weights_yx_RW = attribute_wrapper(comms_annotation=["FPGA_bf_weights_yx_RW"], datatype=numpy.int16, dims=(A_pn * N_beamlets_ctrl, N_pn), access=AttrWriteType.READ_WRITE)
FPGA_bf_weights_yy_R = attribute_wrapper(comms_annotation=["FPGA_bf_weights_yy_R"], datatype=numpy.int16, dims=(A_pn * N_beamlets_ctrl, N_pn))
FPGA_bf_weights_yy_RW = attribute_wrapper(comms_annotation=["FPGA_bf_weights_yy_RW"], datatype=numpy.int16, dims=(A_pn * N_beamlets_ctrl, N_pn), access=AttrWriteType.READ_WRITE)
# ----------
# Summarising Attributes
# ----------
# --------
# Overloaded functions
# --------
# --------
# Commands
# --------
# ----------
# Run server
# ----------
def main(**kwargs):
"""Main function of the SST Device module."""
return entry(Beamlet, **kwargs)
...@@ -97,16 +97,6 @@ class SDP(opcua_device): ...@@ -97,16 +97,6 @@ class SDP(opcua_device):
# Attributes # Attributes
# ---------- # ----------
FPGA_beamlet_output_enable_R = attribute_wrapper(comms_annotation=["FPGA_beamlet_output_enable_R"], datatype=numpy.bool_, dims=(16,))
FPGA_beamlet_output_enable_RW = attribute_wrapper(comms_annotation=["FPGA_beamlet_output_enable_RW"], datatype=numpy.bool_, dims=(16,), access=AttrWriteType.READ_WRITE)
FPGA_beamlet_output_hdr_eth_destination_mac_R = attribute_wrapper(comms_annotation=["FPGA_beamlet_output_hdr_eth_destination_mac_R"], datatype=numpy.str, dims=(16,))
FPGA_beamlet_output_hdr_eth_destination_mac_RW = attribute_wrapper(comms_annotation=["FPGA_beamlet_output_hdr_eth_destination_mac_RW"], datatype=numpy.str, dims=(16,), access=AttrWriteType.READ_WRITE)
FPGA_beamlet_output_hdr_ip_destination_address_R = attribute_wrapper(comms_annotation=["FPGA_beamlet_output_hdr_ip_destination_address_R"], datatype=numpy.str, dims=(16,))
FPGA_beamlet_output_hdr_ip_destination_address_RW = attribute_wrapper(comms_annotation=["FPGA_beamlet_output_hdr_ip_destination_address_RW"], datatype=numpy.str, dims=(16,), access=AttrWriteType.READ_WRITE)
FPGA_beamlet_output_hdr_udp_destination_port_R = attribute_wrapper(comms_annotation=["FPGA_beamlet_output_hdr_udp_destination_port_R"], datatype=numpy.uint16, dims=(16,))
FPGA_beamlet_output_hdr_udp_destination_port_RW = attribute_wrapper(comms_annotation=["FPGA_beamlet_output_hdr_udp_destination_port_RW"], datatype=numpy.uint16, dims=(16,), access=AttrWriteType.READ_WRITE)
FPGA_beamlet_output_scale_R = attribute_wrapper(comms_annotation=["FPGA_beamlet_output_scale_R"], datatype=numpy.uint32, dims=(16,))
FPGA_beamlet_output_scale_RW = attribute_wrapper(comms_annotation=["FPGA_beamlet_output_scale_RW"], datatype=numpy.uint32, dims=(16,), access=AttrWriteType.READ_WRITE)
FPGA_firmware_version_R = attribute_wrapper(comms_annotation=["FPGA_firmware_version_R"], datatype=numpy.str, dims=(16,)) FPGA_firmware_version_R = attribute_wrapper(comms_annotation=["FPGA_firmware_version_R"], datatype=numpy.str, dims=(16,))
FPGA_boot_image_R = attribute_wrapper(comms_annotation=["FPGA_boot_image_R"], datatype=numpy.uint32, dims=(16,), doc="Active FPGA image (0=factory, 1=user)") FPGA_boot_image_R = attribute_wrapper(comms_annotation=["FPGA_boot_image_R"], datatype=numpy.uint32, dims=(16,), doc="Active FPGA image (0=factory, 1=user)")
FPGA_boot_image_RW = attribute_wrapper(comms_annotation=["FPGA_boot_image_RW"], datatype=numpy.uint32, dims=(16,), access=AttrWriteType.READ_WRITE) FPGA_boot_image_RW = attribute_wrapper(comms_annotation=["FPGA_boot_image_RW"], datatype=numpy.uint32, dims=(16,), access=AttrWriteType.READ_WRITE)
...@@ -151,10 +141,6 @@ class SDP(opcua_device): ...@@ -151,10 +141,6 @@ class SDP(opcua_device):
# TODO: needs to not be statically declared as this can change depending on the station and configuration # TODO: needs to not be statically declared as this can change depending on the station and configuration
S_pn = 12 # Number of ADC signal inputs per Processing Node (PN) FPGA. S_pn = 12 # Number of ADC signal inputs per Processing Node (PN) FPGA.
N_pn = 16 # Number of FPGAs per antenna band that is controlled via the SC - SDP interface. N_pn = 16 # Number of FPGAs per antenna band that is controlled via the SC - SDP interface.
A_pn = 6
N_pol = 2
N_beamlets_ctrl = 488
N_pol_bf = 2
# OPC-UA MP only points for AIT # OPC-UA MP only points for AIT
FPGA_signal_input_mean_R = attribute_wrapper(comms_annotation=["FPGA_signal_input_mean_R"], datatype=numpy.double , dims=(S_pn, N_pn)) FPGA_signal_input_mean_R = attribute_wrapper(comms_annotation=["FPGA_signal_input_mean_R"], datatype=numpy.double , dims=(S_pn, N_pn))
...@@ -172,38 +158,6 @@ class SDP(opcua_device): ...@@ -172,38 +158,6 @@ class SDP(opcua_device):
FPGA_signal_input_samples_delay_R = attribute_wrapper(comms_annotation=["FPGA_signal_input_samples_delay_R"], datatype=numpy.uint32, dims=(S_pn, N_pn)) FPGA_signal_input_samples_delay_R = attribute_wrapper(comms_annotation=["FPGA_signal_input_samples_delay_R"], datatype=numpy.uint32, dims=(S_pn, N_pn))
FPGA_signal_input_samples_delay_RW = attribute_wrapper(comms_annotation=["FPGA_signal_input_samples_delay_RW"], datatype=numpy.uint32, dims=(S_pn, N_pn), access=AttrWriteType.READ_WRITE) FPGA_signal_input_samples_delay_RW = attribute_wrapper(comms_annotation=["FPGA_signal_input_samples_delay_RW"], datatype=numpy.uint32, dims=(S_pn, N_pn), access=AttrWriteType.READ_WRITE)
# List of OPC-UA CP for BF beamlets
# cint16[N_pn][A_pn][N_pol][N_beamlets_ctrl]
# Co-polarization BF weights. The N_pol = 2 parameter index is:
# 0 for antenna polarization X in beamlet polarization X,
# 1 for antenna polarization Y in beamlet polarization Y.
FPGA_bf_weights_xx_yy_R = attribute_wrapper(comms_annotation=["FPGA_bf_weights_xx_yy_R"], datatype=numpy.int16, dims=(A_pn * N_pol * N_beamlets_ctrl, N_pn))
FPGA_bf_weights_xx_yy_RW = attribute_wrapper(comms_annotation=["FPGA_bf_weights_xx_yy_RW"], datatype=numpy.int16, dims=(A_pn * N_pol * N_beamlets_ctrl, N_pn), access=AttrWriteType.READ_WRITE)
# cint16[N_pn][A_pn][N_pol][N_beamlets_ctrl]
# Cross-polarization BF weights. The N_pol = 2 parameter index is (note that index pol in range 0:N_pol-1 is the antenna polarization, so index !pol is the beamlet polarization):
# 0 for antenna polarization X in beamlet polarization Y,
# 1 for antenna polarization Y in beamlet polarization X.
FPGA_bf_weights_xy_yx_R = attribute_wrapper(comms_annotation=["FPGA_bf_weights_xy_yx_R"], datatype=numpy.int16, dims=(A_pn * N_pol * N_beamlets_ctrl, N_pn))
FPGA_bf_weights_xy_yx_RW = attribute_wrapper(comms_annotation=["FPGA_bf_weights_xy_yx_RW"], datatype=numpy.int16, dims=(A_pn * N_pol * N_beamlets_ctrl, N_pn), access=AttrWriteType.READ_WRITE)
# cint16[N_pn][N_pol_bf][A_pn][N_pol][N_beamlets_ctrl]
# Full Jones matrix of BF weights.
FPGA_bf_weights_xx_xy_yx_yy_R = attribute_wrapper(comms_annotation=["FPGA_bf_weights_xx_xy_yx_yy_R"], datatype=numpy.int16, dims=(N_pol_bf * A_pn * N_pol * N_beamlets_ctrl, N_pn))
FPGA_bf_weights_xx_xy_yx_yy_RW = attribute_wrapper(comms_annotation=["FPGA_bf_weights_xx_xy_yx_yy_RW"], datatype=numpy.int16, dims=(N_pol_bf * A_pn * N_pol * N_beamlets_ctrl, N_pn), access=AttrWriteType.READ_WRITE)
# cint16[N_pn][A_pn][N_beamlets_ctrl]
# BF weights for separate access to respectively w_xx, w_xy, w_yx, and w_yy.
FPGA_bf_weights_xx_R = attribute_wrapper(comms_annotation=["FPGA_bf_weights_xx_R"], datatype=numpy.int16, dims=(A_pn * N_beamlets_ctrl, N_pn))
FPGA_bf_weights_xx_RW = attribute_wrapper(comms_annotation=["FPGA_bf_weights_xx_RW"], datatype=numpy.int16, dims=(A_pn * N_beamlets_ctrl, N_pn), access=AttrWriteType.READ_WRITE)
FPGA_bf_weights_xy_R = attribute_wrapper(comms_annotation=["FPGA_bf_weights_xy_R"], datatype=numpy.int16, dims=(A_pn * N_beamlets_ctrl, N_pn))
FPGA_bf_weights_xy_RW = attribute_wrapper(comms_annotation=["FPGA_bf_weights_xy_RW"], datatype=numpy.int16, dims=(A_pn * N_beamlets_ctrl, N_pn), access=AttrWriteType.READ_WRITE)
FPGA_bf_weights_yx_R = attribute_wrapper(comms_annotation=["FPGA_bf_weights_yx_R"], datatype=numpy.int16, dims=(A_pn * N_beamlets_ctrl, N_pn))
FPGA_bf_weights_yx_RW = attribute_wrapper(comms_annotation=["FPGA_bf_weights_yx_RW"], datatype=numpy.int16, dims=(A_pn * N_beamlets_ctrl, N_pn), access=AttrWriteType.READ_WRITE)
FPGA_bf_weights_yy_R = attribute_wrapper(comms_annotation=["FPGA_bf_weights_yy_R"], datatype=numpy.int16, dims=(A_pn * N_beamlets_ctrl, N_pn))
FPGA_bf_weights_yy_RW = attribute_wrapper(comms_annotation=["FPGA_bf_weights_yy_RW"], datatype=numpy.int16, dims=(A_pn * N_beamlets_ctrl, N_pn), access=AttrWriteType.READ_WRITE)
# ---------- # ----------
# Summarising Attributes # Summarising Attributes
# ---------- # ----------
......
# -*- coding: utf-8 -*-
#
# This file is part of the LOFAR 2.0 Station Software
#
#
#
# Distributed under the terms of the APACHE license.
# See LICENSE.txt for more info.
from .base import AbstractTestBases
from tangostationcontrol.integration_test.device_proxy import TestDeviceProxy
class TestDeviceBeamlet(AbstractTestBases.TestDeviceBase):
def setUp(self):
"""Intentionally recreate the device object in each test"""
super().setUp("STAT/Beamlet/1")
def test_device_read_all_attributes(self):
# We need to connect to SDP first to read some of our attributes
self.sdp_proxy = self.setup_sdp()
super().test_device_read_all_attributes()
def setup_sdp(self):
# setup SDP, on which this device depends
sdp_proxy = TestDeviceProxy("STAT/SDP/1")
sdp_proxy.off()
sdp_proxy.warm_boot()
sdp_proxy.set_defaults()
return sdp_proxy
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment