Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I parallelize input and display in MATLAB?

I'm using Psychtoolbox in MATLAB to run a behavioral psychology paradigm. As part of the paradigm, users have to view a visual stimulus and respond to it using some input mechanism. For a keyboard, this works as follows:

  1. show stimulus
  2. poll keyboard for response
    1. if no response detected, loop back to 1
    2. if response detected, break and move on with script

This works fine for a keyboard, as step 2 takes between 1-2 ms. The problem comes when I use an alternate input mechanism; in that case, step 2 takes ~20 ms. (I need this alternate input to run the study, and that should be considered immutable fact.) As the stimulus changes with a very short timespan, this added delay breaks the task.

My current thought is to try to use the parallel processing, such that one thread shows the stimulus, and another thread polls the keyboard. I'm currently using the Parallel Computing Toolbox to do this. The problem I'm having is that I don't know how to direct keyboard input to a "parallelized" thread. Does anyone know (1) whether it's possible to direct keyboard input to a thread / have a thread send a visual signal to a monitor, and if yes, (2) how to do it?

Also, if anyone has any better ideas as to how to approach this problem, I'm all ears.

like image 288
eykanal Avatar asked Dec 10 '10 15:12

eykanal


2 Answers

According to this MATLAB newsgroup thread, it appears that threads can't modify graphics objects. Only the desktop MATLAB client can do that. This means that you can't handle updating of graphics from a thread, and I can confirm this as I tried it and wasn't able to modify figures or even the root object from a thread.

However, I think you may be able to do the main graphics updating in MATLAB while a thread handles polling for your input. Here's a sample function for continuously updating a display until a thread waiting for input from KbCheck is finished running:

function varargout = plot_until_input

  obj = createJob();                                   %# Create a job
  task = createTask(obj,@get_input,4,{deviceNumber});  %# Create a task
  submit(obj);                                         %# Submit the job
  waitForState(task,'running');  %# Wait for the task to start running

  %# Initialize your stimulus display here
  while ~strcmp(get(task,'State'),'finished')  %# Loop while the task is running
    %# Update your stimulus display here
  end

  varargout = get(task,'OutputArguments');  %# Get the outputs from the task
  destroy(obj);                             %# Remove the job from memory

%#---Nested functions below---

  function [keyIsDown,secs,keyCode,deltaSecs] = get_input(deviceNumber)
    keyIsDown = false;
    while ~keyIsDown  %# Keep looping until a key is pressed
      [keyIsDown,secs,keyCode,deltaSecs] = KbCheck(deviceNumber);
    end
  end

end

I was able to successfully run the above function with some simple plotting routines and replacing the code in get_input with a simple pause statement and a return value. I'm unsure whether KbCheck will work in a thread, but hopefully you will be able to adapt this for your needs.

Here's the documentation for the Parallel Computing Toolbox functions used in the above code: createJob, createTask, submit, waitForState, destroy.

like image 182
gnovice Avatar answered Sep 29 '22 11:09

gnovice


I don't know of a way how you could do this with parallel processing.

However, a feature you might be able to use is the timer object. You would set up the timer object to poll the input mechanism, and, if anything is detected, change the value of a global variable. Then, you start your stimulus routine. In the while-loop in which you're updating the display, you keep checking the global variable for a change from the timer object.

like image 27
Jonas Avatar answered Sep 29 '22 12:09

Jonas