Scanbox has a memory mapped mechanism to share the incoming data stream with other processes that intend to consume the data in real-time.
Examples of simple uses of such data sharing include the calculation of rolling averages, displaying a real-time histogram, or generating a montage display for volumetric data.
Of course, different experiments may need to be processed by different plug-ins. To simplify this process we now provide a single mechanism that allows the selection of a plug-in via a pull-down menu in the Scanbox GUI.
The configuration variable “plugin” can be used to list a number of different options to call. In the example below, two possible options are listed.
sbconfig.plugin = {'rolling','montage'}; %plugin options
These must be names of Matlab scripts that will be called to process the data.
When Scanbox starts it will list these options in a pull down menu within the real-time processing panel, along with two check-boxes, one labeled “plugin” and another labeled “focus”.
The pull down menu allows the user to select one plugin among the available selections.
The plug-in checkbox indicates you want the data to be shared via the memory mapped mechanism, and the “focus” checkbox indicates whether you want the data to be shared not only during a grabbing operation, but also when you are focusing.
For example, adjusting the laser intensity by analyzing the histogram of values in the incoming data may be something you want to do ahead of an actual experiment, and something you will want to run while focusing.
Now, when you start Scanbox a new Matlab instance is opened and calls the sbxplugin_server.m script (assuming mmap=true in the config file). This is a simple script that waits for new data to arrive and calls the selected plug-in.
% Scanbox plug in server script % This code will run upon startup of Scanbox on a separate matlab instance if mmap=true % in the scanbox_config file % Open memory mapped file -- define just the header first scanbox_config; % read the scanbox config structure mmfile = memmapfile('scanbox.mmap','Writable',true, ... 'Format', { 'int16' [1 16] 'header' } , 'Repeat', 1); flag = 1; disp('Plugin server ready'); % Process all incoming frames until Scanbox stops running = false; while(true) disp('Waiting for imaging data stream'); while ~running running = mmfile.Data.header(1)>=0; end plugin_id = mmfile.Data.header(7); % get the plug in to be used fprintf('Plugin id=%d\n',plugin_id); fprintf('ROI=%d Expt=%d\n',mmfile.Data.header(8),mmfile.Data.header(9)); while running running = (mmfile.Data.header(1) ~= -2); % no stop signal present if running && mmfile.Data.header(1)>=0 % if not stopped and frame present switch plugin_id case 1 % replace the line below with your own script for % plugin with id #1 fprintf('Frame: %05d Plugin: %d\n',mmfile.Data.header(1),plugin_id); case 2 % replace the line below with your own script for % plugin with id #2 fprintf('Frame: %05d Plugin: %d\n',mmfile.Data.header(1),plugin_id) otherwise disp('Invalid plugin id number'); end mmfile.Data.header(1) = -1; % signal Scanbox that frame has been consumed! end end end clear(mmfile); % close the memory mapped file close all; % close all figures
The default server code simply lists number of of the incoming frame and the selected plug-in. Just add an eval() call to the script name at the indicated locations.
The output of the script, as is, will look like:
Waiting for imaging data stream Plugin id=2 ROI=0 Expt=0 Frame: 00000 Plugin: montage Frame: 00001 Plugin: montage Frame: 00002 Plugin: montage Frame: 00003 Plugin: montage Frame: 00004 Plugin: montage Frame: 00005 Plugin: montage Frame: 00006 Plugin: montage Frame: 00007 Plugin: montage Frame: 00008 Plugin: montage Frame: 00009 Plugin: montage Frame: 00010 Plugin: montage Waiting for imaging data stream
The user can now easily switch between plugins from the Scanbox window by changing the selection in the pull down menu.
Hi Dario,
It seems like the example code for the plugins that you’ve posted only access the green PMT (PMT0). If I want to change the code to display a rolling average for the red PMT (PMT1), how would I do that? I can’t tell from the code itself where it chooses which PMT to read from.
Thanks!
Mark
Hi Mark.. At the moment only PMT0 (green) is shared… but it is an easy change to allow you to be able to select between red/green or both. I put this in the list of things to do. It won’t take long.