=============================================================================
realtime_receiver.py - program to receive and display real-time plugin data
This program receives motion parameters and optionally ROI averages
or voxel data each TR from the real-time plugin to afni. Which data
will get sent is controlled by the real-time plugin. All data is
sent as floats.
Motion parameters: 6 values per TR
ROI averages: N values per TR, where N is the number of ROIs
All voxel data: 8 values per voxel per TR (might be a lot of data!)
The 8 values include voxel index, 3 ijk indices,
the 3 xyz coordinates, and oh yes, the data
Examples:
1a. Run in test mode to display verbose data on the terminal window.
realtime_receiver.py -show_data yes
1b. Run in test mode to just display motion to the terminal.
realtime_receiver.py -write_text_data stdout
1c. Write all 'extra' parameters to file my_data.txt, one set
per line.
realtime_receiver.py -write_text_data my_data.txt \
-data_choice all_extras
2. Provide a serial port, sending the Euclidean norm of the motion params.
realtime_receiver.py -show_data yes -serial_port /dev/ttyS0 \
-data_choice motion_norm
3. Run a feedback demo. Assume that the realtime plugin will send 2
values per TR. Request the receiver to plot (a-b)/(a+b), scaled
to some small integral range.
realtime_receiver.py -show_demo_gui yes -data_choice diff_ratio
4. Adjust the defaults of the -data_choice diff_ratio parameters from
those for AFNI_data6/realtime.demos/demo.2.fback.1.receiver, to those
for the s620 demo:
realtime_receiver.py -show_demo_gui yes -data_choice diff_ratio -dc_params 0.008 43.5
TESTING NOTE:
This following setup can be tested off-line using Dimon, afni and this
realtime_receiver.py program. Note that while data passes from Dimon
to afni to realtime_receiver.py, the programs essentially should be
started in the reverse order (so that the listener is always ready for
the talker, say).
See the sample scripts:
AFNI_data6/realtime.demos/demo.2.fback.*
step 1. start the receiver: demo.2.fback.1.receiver
realtime_receiver.py -show_data yes -show_demo_gui yes \
-data_choice diff_ratio
step 2. start realtime afni: demo.2.fback.2.afni
Note: func_slim+orig is only loaded to ensure a multiple
volume overlay dataset, so that the rtfeedme command
"DRIVE_AFNI SET_SUBBRICKS 0 1 1" finds sub-brick 1.
# set many REALTIME env vars or in afni's realtime plugin
setenv AFNI_REALTIME_Registration 3D:_realtime
setenv AFNI_REALTIME_Base_Image 2
setenv AFNI_REALTIME_Graph Realtime
setenv AFNI_REALTIME_MP_HOST_PORT localhost:53214
setenv AFNI_REALTIME_SEND_VER YES
setenv AFNI_REALTIME_SHOW_TIMES YES
setenv AFNI_REALTIME_Mask_Vals ROI_means
setenv AFNI_REALTIME_Function FIM
cd ../afni
afni -rt -yesplugouts \
-com "SWITCH_UNDERLAY epi_r1+orig" \
-com "SWITCH_OVERLAY func_slim+orig" &
# at this point, the user should open a graph window and:
# FIM->Ignore->2
# FIM->Pick Ideal->epi_r1_ideal.1D
step 3. feed data to afni (can be repeated): demo.2.fback.3.feedme
cd ../afni
set episet = epi_r1+orig
set maskset = mask.left.vis.aud+orig
plugout_drive -com "SETENV AFNI_REALTIME_Mask_Dset $maskset" -quit
rtfeedme \
-drive 'DRIVE_AFNI OPEN_WINDOW axialimage geom=285x285+3+533' \
-drive 'DRIVE_AFNI OPEN_WINDOW axialgraph keypress=A' \
-drive 'DRIVE_AFNI SET_SUBBRICKS 0 1 1' \
-drive 'DRIVE_AFNI SET_DICOM_XYZ 52 4 12' \
-drive 'DRIVE_AFNI SET_FUNC_RANGE 0.9' \
-drive 'DRIVE_AFNI SET_THRESHNEW 0.4' \
-dt 200 -3D $episet
COMMUNICATION NOTE:
This program listens for connections at TCP port 53214, unless an
alternate port is specified. The real-time plugin (or some other
program) connects at that point, opening a new data socket. There
is a "handshake" on the data socket, and then data is received until
a termination signal is received (or the socket goes bad).
Data is sent per run, meaning the connection should be terminated
and restarted at the end of each run.
The handshake should be the first data on the data socket (per run).
The real-time plugin (or other program) will send the hello bytes:
0xabcdefab, where the final byte may be incremented by 0, 1 or 2
to set the version number, e.g. use 0xabcdefac for version 1.
Version 0: only motion will be sent
Version 1: motion plus N ROI averages will be sent
Version 2: motion plus all voxel data for N voxels will be sent
- this is dense - 8 values per voxel
- 1Dindex, i, j, k, x, y, z, value
Version 3: motion plus voxel data for N voxels will be sent
- "light" version of 2, only send one 'value' per voxel
Version 4: mix of 1 and 3: motion, N ROI aves, M voxel values
If the version is 1, 2 or 3, the 4-byte handshake should be followed
by a 4-byte integer, specifying the value of N. Hence, the
combination of the version number and any received N will determine
how much data will be sent to the program each TR.
For version 4, the 4-byte handshake should be followed by 2 4-byte
integers, one to specify N (# ROI aves), one to specify M (# vox).
At the end of the run, the sending program should send the 4-byte
good-bye sequence: 0xdeaddead.
This program is based on the structure of serial_helper, but because
it is meant as a replacement, it will have different options.
------------------------------------------
Options:
terminal options:
-help : show this help
-hist : show module history
-show_valid_opts : list valid options
-ver : show current version
other options
-data_choice CHOICE : pick which data to send as feedback
motion : send the 6 motion parameters
motion_norm : send the Euclidean norm of them
all_extras : send all 'extra' values (ROI or voxel values)
diff_ratio : (a-b)/(abs(a)+abs(b)) for 2 'extra' values
* To add additional CHOICE methods, see the function compute_TR_data().
-extras_on_one_line yes/no: show 'extras' on one line only
(default = no)
-dc_params P1 P2 ... : set data_choice parameters
e.g. for diff_ratio, params P1 P2
P1 = dr low limit, P2 = scalar -> [0,1]
result is (dr-P1)*P2 {applied in [0,1]}
-serial_port PORT : specify serial port file for feedback data
-show_comm_times : display communication times
-show_data yes/no : display incoming data in terminal window
-show_demo_data : display feedback data in terminal window
-show_demo_gui : demonstrate a feedback GUI
-swap : swap bytes incoming data
-tcp_port PORT : specify TCP port for incoming connections
-verb LEVEL : set the verbosity level
-write_text_data FNAME : write data to text file 'FNAME'
-----------------------------------------------------------------------------
R Reynolds July 2009
=============================================================================