Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Setup (heartbeat) communication between the ZMQInterface and Falcon (C++ software) #1

Open
MarineChap opened this issue Nov 3, 2020 · 10 comments · May be fixed by #2
Open

Setup (heartbeat) communication between the ZMQInterface and Falcon (C++ software) #1

MarineChap opened this issue Nov 3, 2020 · 10 comments · May be fixed by #2

Comments

@MarineChap
Copy link

Hello,

I am trying to port OpenEphys data in Falcon (low latency graph computation software) in particular to use it with the neuropixels and to do this I was trying to use this ZMQ communication.
However, I am little lost. Just subscribe to the Data socket does not work. The doc said that setup the heartbeat is primordial. Could you give me more info ? What to send, what format, what frequency, what expecting as answer ?
This will trigger the data ? Do you have an example for C++ data ?

Thank you for your answer.
Have a good day.

@MarineChap
Copy link
Author

I made some progress. I am receiving the data and I can
For reference, this is the information I discover along the road which could be useful to add in the doc.

  • No need the heartbeat communication (?)
  • The socket can be connected if openEphys acquisition is ON , but the data are actually sent only when recording is ON.

I am still wondering what is the difference between real sample and number of samples. Could you explain me how to correctly read the data packet in C++ please ? I am little lost here.
Thank you
Have a good day

@anjaldoshi
Copy link
Collaborator

Hi Marine,

We don't have an example for setting up a C++ client with the ZMQInterface plugin as it was developed by someone outside the Open Ephys team, but the original repo has an example python client that you can refer to and try to replicate it in your C++ code. The python example can be found here: https://github.com/aszell/ZMQInterface/tree/master/python_clients/ZMQPlugins

There are two scripts in this examples, the first one plot_process_zmq.py has all the setup required to communicate with ZMQInterface plugin, and the second script simple_plotter_zmq.py plots the raw data using matplotlib recevied via ZMQInterface.

Also, currently, there is no GUI editor on the plugin that allows you to change the data socket. It is fixed to 5556. I'll add the feature to change the socket via the editor soon.

I can work on a C++ example, but It'll take some time before I can provide with you one. If you figure this out before me, I'll be more than happy to include your C++ example in this repo.

@MarineChap
Copy link
Author

Hello Anjaldoshi,
Ok, I understand the problem then, don't bother you to develop a C++ example as I will be able to give one soon. I have the communication working but I am not sure the way that I read the data and resize the array is not corrupting the data. I will need to develop a test to verify I have actually the right data read.

I have been using the OPETH code to figure out some stuffs about this communication. But thank you for the python example.
I think I am figuring out more and more stuffs.

Could you just give me some tips please ?

  • how the data are packaged and sent in the data packet ?
  • In the header, what is real number of sample against number of sample ?
  • Does it send the data as soon as it is received from the OpenEphys graph or it waits to fill a certain buffer (size?) ? In that later case, it would be good to make this buffer resizable in the ui too.

Thank you.

@anjaldoshi
Copy link
Collaborator

How the data are packaged and sent in the data packet ?

The data is packaged in size of number of channels * number of samples. You should refer to ZmqInterface::sendData() where you can see data packaging on this line. The data comes in from the process() method which gets sent from the Source processor via Open Ephys' internal mechanism.

In the header, what is real number of sample against number of sample ?

The real number of samples is how many samples a Source processor has per channel, and the number of samples is the value of how many samples per channel are present in the actual data buffer which gets copied into the data packet. They both should ideally be same. The data packet size takes into account the number of samples and not then real number of samples as seen in sendData().

Does it send the data as soon as it is received from the OpenEphys graph or it waits to fill a certain buffer (size?) ? In that later case, it would be good to make this buffer resizable in the ui too

As the data gets sent from the Source processor to downstream processors (ZMQInterface in this case ) via process() method in buffers, where the buffer size is equal to the number of channels * number of samples, it is not advisable to change the buffer size manually. Changing that would break a lot of things.

Let me know if you have any further questions.

Best,
Anjal

@MarineChap
Copy link
Author

I am working with the example datasets of OpenEphys: data_stream_16ch_cortex
and I am having a really different number between n_real_samples and the n_samples:
{"content":{"n_channels":16,"n_real_samples":928,"n_samples":1024,"sample_rate":40000,"timestamp":5832480},"data_size":65536,"message_no":6287,"type":"data"}
So, I am not sure to understand what to do with the difference.

Thank for your help. I am very close to the solution but I still have problem to correctly parsing the data and having a logical output.

@anjaldoshi
Copy link
Collaborator

The reason behind the difference is that the buffer width is set to a fixed number of samples (n_samples), which is 1024 in this case, but the the number of samples (n_real_samples) being written in the buffer itself can be less than that (928 in this case). This means the remaining (1024 - 928 = 96) samples are empty.
So, in your C++ client, just like in this python example you can simply resize the data received in the packet to match the size of n_real_samples.

@MarineChap
Copy link
Author

MarineChap commented Nov 8, 2020

Hello.
It is working ! :) Thank you for your help.
Are you still interested by a C++ example? I can do a self-isolated example with a PR here or in another repo somewhere or just linked to you the code in Falcon. Tell me what you are preferring.
Have a good day,
Marine

@anjaldoshi
Copy link
Collaborator

That's great!
Yes, we would love to include your C++ example in this repo. You can do a PR here that includes the C++ example source code as well as all the dependencies required to run the example. If you can, please write a description or include a README with the PR so that we can add that to our docs to make it easier for others to follow. Please let me know If I can be of any help with this.

Thank you for all the work you've done!

@MarineChap
Copy link
Author

Hello,
What json lib are you using ? I cannot find it in this plugin, is it part of the main OpenEphys gui?
It would be more uniform to use the same lib in the example.
From my side, I am using this one from nlohmann.
Mainly, because of the lightway and easy way to to add this dependency through fetch_content in a cmake.

Have a good day

@anjaldoshi
Copy link
Collaborator

We don't use any external JSON library, it is already included with the underlying JUCE API in the main GUI. As, you are setting up a client, which cannot use the main GUI's underlying API, you'll have to use an external JSON library.

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 a pull request may close this issue.

2 participants