How do I execute two MATLAB scripts simultaneously? The one script is recording an EEG measurement while the other script is generating a visual stimuli on the screen. I hope that it is possible! And if it is, it would be nice with a code example.
The script for recording EEG is:
fs= 256; measurement_time=10; %% Setting up the dataloggers % Set up the communication with the dataloggers ai = analoginput('guadaq',1); Serial = ai.DeviceSerial;
addchannel(ai,); % Apply general filtering set(ai.Channel(1),'BPIndex',45); % bandpassfilter the raw-input set(ai.Channel(1),'NotchIndex',2); % notchfilter the raw-input
% specify samplefrequency and the total number of samples that should % be obtained before stopping the datatransfer set(ai,'SampleRate',fs,'SamplesPerTrigger',measurement_time*fs);
% Define the filename for logging the data to harddisk. LoggingMode is set to Disk in order % to stream the data to the harddisk. Use Disk&Memory to stream the data to harddisk and to % memory. LogToDiskMode is set to Overwrite to replace an existing file with the same % name. set(ai,'LogFileName','test','LoggingMode','Disk','LogToDiskMode','Overwrite');
start(ai) while ai.SamplesAcquired< measurement_time*fs end
data = getdata(ai);
plot(data), grid on
% Saving the data file outputfile= 'measurement.mat'; save(outputfile, 'data');
delete(ai) clear ai-----
The script for generating a visual stimuli is:
% ---------------------- Psychophysics Toolbox --------------------------- % By using the Matlab toolbox - psychophysics - two flickering squares are % implemented. The program uses the refresh rate of the screen in order to % generate flicker, by shifting a chosen area between the background color % (black) and a set color - here white.
% Last edited 7th of February 2011 % ------------------------------------------------------------------------ screenNum=0; flipSpd=0; [wPtr,rect]=Screen('OpenWindow',screenNum); % wPtr - designate the window, rect - screen size monitorFlipInterval=Screen('GetFlipInterval', wPtr); % Refresh time [s] frame_rate = 1/monitorFlipInterval; % Frame rate [Hz]
%% ----------------------------------------------------------------------- p=8; % Sets the frequency for left hand square P = frame_rate/(2*p); % Frequency [Hz] q=4; % Sets the frequency for right hand square Q = frame_rate/(2*q); % Frequency [Hz] color_black = [255 255 255]; % Defining black color color_white = [0 0 0]; % Defining white colot CenX = rect(3)/2; % Center of width CenY = rect(4)/2; % Center of height Dis = 200; % Distance between the two squares SqS = 300; % Square size pos1=[CenX-Dis/2-SqS CenY-SqS/2 CenX-Dis/2 CenY+SqS/2]; % Position of left hand square pos2=[CenX+Dis/2 CenY-SqS/2 CenX+Dis/2+SqS CenY+SqS/2]; % Position of right hand square
black=BlackIndex(wPtr); % Find the color lookup table values (black) white=WhiteIndex(wPtr); % Find the color lookup table values (white)
Screen('FillRect',wPtr,black); % Fills a rectangle the size of the screen to be black Screen(wPtr, 'Flip'); % Flip the screen from offscreen to onscreen HideCursor; tic while toc<1; end
Screen('FillRect',wPtr,black); % Blacks the screen vbl=Screen(wPtr, 'Flip'); % Collect the time for the first flip with vbl
for i=1:300 % "time of run" % Generate the flickering squares if mod(i,p)==0 Screen('FillRect',wPtr,color_black, pos1); else Screen('FillRect',wPtr,color_white, pos1); end
if mod(i,q)==0 Screen('FillRect',wPtr,color_black, pos2); else Screen('FillRect',wPtr,color_white, pos2); end
Screen('FillRect',wPtr,black); % Blacks the screen vbl=Screen(wPtr, 'Flip', vbl+(flipSpd*monitorFlipInterval)); tic while toc<1; end tic Screen('CloseAll'); ShowCursor-------
Can you tell if your code will work, Paulo?
No products are associated with this question.
I am using matlab to control a neurophysiological data aquisition system (DAQ, plexon omniplex), and am also using the psychophysics toolbox (PTB) to generate stimuli, so basically doing what you need to do. You have the following problem much greater than simply running two scripts:
My solutions are the following: I control the omniplex using my PTB code, it uses a LabJack to send out physical voltage pulses (immediately after Screen('flip') in the PTB code!) to control my electrophysiological data aquisition system. I've tested this by feeding these TTLs into my DAQ, and also recording a signal from a photodiode on the screen that displays output from the PTB to ensure they are synchronised together. Without this, you cannot know whether your stimulus and response really are properly aligned, and this will impact your interpretation of your results.
To see my data coming in online I have to use a different matlab script and I simply open another matlab instance. You can spawn secondary matlab sessions that run your script programatically from your first script (assuming you want to run a script called myScript.m), using:
eval('!matlab -nodesktop -nosplash -r "myScript.m" &')
eval('!osascript -e ''tell application "Terminal"'' -e ''activate'' -e ''do script "matlab -nodesktop -nosplash -maci -r \"myScript.m\""'' -e ''end tell''')
To communicate between these two matlab scripts I use UDP using pnet (it comes with PTB, also available on matlab file exchange) to allow both matlab scripts to talk to each other, pass variables and keep my data visualisation locked to what the stimulus was/is doing. You can for example use UDP packet after the Screen('flip') in PTB so your EEG system knows within a few milliseconds when your display changed if you don't know how to use a photodiode to check this.
Another solution, and one I thought was too limited for my needs but may work for you is the Parallel computing toolbox, see this interesting stack overflow question:
You cannot run two scripts simultaneously in Matlab. Although you can start different threads in e.g. C, there is no guarantee, that the threads are performed simultaneously, because the OS decides about the order of execution and distribution to the different cores. Either you have to use a real-time OS and e.g. C. Or you can start two Matlab instances to run the two programs. Then I assume you need a synchronization, e.g. a light-diode scanning the screen - this has the advantage, that even the delay between Matlab's figure update and the display on the screen is considered.
I made this code yesterday, it displays the memory used by matlab in real time, it updates the plot every half second, in your case it might work with only a timer but you could add another timer with almost the same parameters except the callback function, for example t would record the EEG and t1 would generate the stimuli, in the callback functions you can just insert the m file name you already have for each job you want to perform.
Without knowing more about your scripts it's not easy to know if this approach would work.
function test fig=figure;[user,sys] = memory;a=0; set(fig,'CloseRequestFcn','delete(gcf);') ax=axes;set(ax,'Ylimmode','manual'); h = plot(ax,NaN, NaN,'LineWidth',5); set(ax,'Ylimmode','manual'); set(ax,'YLim',[0 sys.PhysicalMemory.Total/10^6]) ylabel('Memory used by matlab in Megabytes'); t = timer('TimerFcn',@readdata,... 'Period', 0.5,'executionmode','fixedSpacing');start(t) function readdata(g1,gg1) if (~ishandle(fig)),stop(t),return,end m=memory;mem=m.MemUsedMATLAB; set(h,'XData', [get(h, 'XData'), a],... 'YData', [get(h, 'YData'), mem/10^6]); xd=get(h,'XData');yd=get(h,'YData');a=a+1; if numel(xd)>=100 set(h,'XData',[xd(80:100)]);set(h,'YData',[yd(80:100)]); end end end
The Data Acquisition Toolbox has the exact capability you want built in. There's a demo called "Using Callback Functions to Create Live Displays and Analysis" that is part of the product that teaches you how to do this.
Also, check out the "daqscope" demo that is part of the toolbox for a real world example of plotting the data as it arrives. It's more complex, but shows many of the techniques in a full application.
Manager of Test and Measurement