Skip to content

Stream iq#582

Merged
RemingtonRohel merged 5 commits into
developfrom
stream_iq
Jul 23, 2026
Merged

Stream iq#582
RemingtonRohel merged 5 commits into
developfrom
stream_iq

Conversation

@RemingtonRohel

Copy link
Copy Markdown
Contributor

Allows Borealis to stream any type of data (antennas_iq, bfiq, rawacf, or fitacf) over the wire.

  • Uses multipart message with topic to differentiate messages, first item is of form file_type/slice_id (e.g. antennas_iq/0, fitacf/2).
  • Requires downstream user to set up a zmq SUB socket to connect, and they have the option to filter messages by type or slice ID. They also need Borealis in order to unpickle the SliceData packets being sent over the socket, if accepting antennas_iq/bfiq/rawacf messages.

* Can serve antennas_iq and/or bfiq and/or rawacf and/or fitacf (fitacf as DMAP)
* Receiver responsible for unpickling SliceData and storing as HDF5 or DMAP
* realtime simulator needs SliceData object for testing now, not DMAP data
* Messages sent with topic of "file_type/slice_id", for filtering with receivers zmq SUB socket.
* Use one socket for data_write -> realtime comms, added header to
  message to differentiate between file types
* Updated realtime_sim.py to accurately test realtime.py functionality
  (realtime_server function).
* Moved flags for streaming to CLI args for realtime.py, instead of
  data_write.py (more logical grouping, realtime will always receive
data from data_write and will be in charge of streaming it or not).
@RemingtonRohel RemingtonRohel linked an issue Jun 30, 2026 that may be closed by this pull request
@RemingtonRohel

Copy link
Copy Markdown
Contributor Author

TODO: test which messages are all sent over-the-wire if, for example, a subscriber only wants FITACF data. I suspect that all messages are sent, as zmq specifies that messages are filtered on the subscriber end. If so, we may be able to fix this by splitting the single publisher in the realtime module to one publisher per file type (possibly and per slice ID), then adding an intermediary. The intermediary would be the endpoint for external connections, and the subscription filtering might be able to happen at the intermediary (which is running on the radar computer) as opposed to on the external subscriber.

* Sends pickled dictionaries over the wire, then depickles and turns into SliceData object subscriber-side.
* Created script to subscribe, filter by topic, and write to file.
@RemingtonRohel

Copy link
Copy Markdown
Contributor Author

It seems that the Publisher also filters messages for certain transports, including TCP (which is used in this implementation), from zeromq/libzmq#3611. So, no further work to do.

@RemingtonRohel

Copy link
Copy Markdown
Contributor Author

Testing idea: Run steamed_sham.py on a site computer that isn't running the radar (shut off data_flow first so that the files aren't accidentally distributed), then connect to the stream on sdc-serv and verify operation.

@RemingtonRohel

Copy link
Copy Markdown
Contributor Author

Tested by running steamed_sham.py on sasbore206, connected with sdc-serv using the process_realtime.py script. Was able to subscribe to all HDF5 file types, and write to file, no problems encountered.

@tjk584 tjk584 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, just a few clarifying questions

Also, documentation should be added on this before a new release

socket = ctx.socket(zmq.SUB)
socket.setsockopt(zmq.SUBSCRIBE, topic.encode("utf-8"))
socket.setsockopt(zmq.RCVTIMEO, 100) # time out after 100 ms
socket.connect(f"tcp://127.0.0.1:{port}")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this set to localhost because our radar sites are configured with autossh?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup, this could be folded into a command-line option but for now this will work for our purposes.

parser.add_argument(
"in_ports", nargs="+", type=int, help="Ports to accept Borealis data from"
)
parser.add_argument("--topic", default="bfiq", help="Topic to subscribe to")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What are the possible topics?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The topics are formatted as [file_type]/[slice_id], e.g. antennas_iq/0, bfiq/2, etc. The subscription filter matches prefixes, so specifying a topic of bf will match bf* in the message topic. In the future, you could extend this script to handle multiple topic subscriptions (multiple calls of socket.setsockopt(zmq.SUBSCRIBE, topic)), and you will receive multiple types of message, or receive all types from just a single slice ID or something.

Comment thread src/brian.py

# Check if message was intended for realtime, and drop the message if so
if sender.decode("utf-8") == options.dw_to_rt_identity:
if receiver.decode("utf-8") == options.rt_to_dw_identity:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Was this a bug previously?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not a bug, I don't remember why I changed this, I think it felt more clear at the time to check the recipient

Comment thread src/data_write.py
Comment on lines -352 to +365
def _write_correlations(
def _package_write_stream(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like the consistent function names

@RemingtonRohel
RemingtonRohel merged commit 32d36db into develop Jul 23, 2026
2 of 3 checks passed
@RemingtonRohel
RemingtonRohel deleted the stream_iq branch July 23, 2026 21:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Streaming IQ data

2 participants