Diff for "ScannerSyncMatlab" - MRC CBU Imaging Wiki
location: Diff for "ScannerSyncMatlab"
Differences between revisions 9 and 12 (spanning 3 versions)
Revision 9 as of 2013-03-07 21:23:43
Size: 4814
Editor: localhost
Comment: converted to 1.6 markup
Revision 12 as of 2015-08-28 14:38:35
Size: 5551
Comment:
Deletions are marked like this. Additions are marked like this.
Line 1: Line 1:
= Using ScannerSync from Matlab = NB - as of early 2015, the method of using scanner sync in matlab has changed. The new method uses Tibor's ScannerSynchClass rather than Rhodri's MRISync / ScannerSync software,
Line 3: Line 3:
= Using ScannerSync from Matlab - NEW METHOD =
= Using ScannerSync from Matlab - OLD METHOD =
Line 10: Line 12:
numdummies=8;  numdummies=8;
Line 15: Line 17:
invoke(objSS,'SetMSPerSample',2); %Set StartExperiment routines’ sampling  invoke(objSS,'SetMSPerSample',2); %Set StartExperiment routines’ sampling
Line 17: Line 19:
Line 24: Line 25:
Wait for dummies (one less as StartExperiment command above will already have heard a pulse)
Line 25: Line 27:
Wait for dummies (one less as StartExperiment command above will already have heard a pulse)
Line 33: Line 34:
end;  end;
Line 35: Line 36:
In your trial loop, you'll need to spend some of the time listening for pulses
Line 36: Line 38:
In your trial loop, you'll need to spend some of the time listening for pulses
Line 40: Line 41:
You should dump out the timing of critical events and the measured TR
Line 41: Line 43:
You should dump out the timing of critical events and the measured TR
Line 47: Line 48:
}}}
Also, for some designs you may want to occasionally synchronise your trials to the scanner
Line 48: Line 51:
}}}

Also, for some designs you may want to occasionally synchronise your trials to the scanner
Line 54: Line 54:

Line 68: Line 66:
  invoke(objSS,'SetPretendMode',1)    invoke(objSS,'SetPretendMode',1)
Line 70: Line 68:
invoke(objSS,'SetMSPerSample',2); %Set StartExperiment routines’ sampling  invoke(objSS,'SetMSPerSample',2); %Set StartExperiment routines’ sampling
Line 72: Line 70:
Line 75: Line 72:
If you would like to use the button box in the practice room of the Scanner building, you will need this code instead to make the button box work:  If you would like to use the button box in the practice room of the Scanner building, you will need this code instead to make the button box work:
Line 84: Line 81:
  invoke(objSS,'SetPretendModeExtended',1,0) 
  invoke(objSS,'Initialize','') %Initialise the Keithley board and object 
  invoke(objSS,'SetPretendModeExtended',1,0)
  invoke(objSS,'Initialize','') %Initialise the Keithley board and object
Line 87: Line 84:
invoke(objSS,'SetMSPerSample',2); %Set StartExperiment routines’ sampling  invoke(objSS,'SetMSPerSample',2); %Set StartExperiment routines’ sampling
Line 89: Line 86:
Line 91: Line 87:
Line 107: Line 102:
This will collect the responses made by the subject during a pre-defined time interval (rt_window). You can also need to define which buttons the subject should press (in this example they are called samekey and diffkey). The codes returned by pressing the buttons are 28, 26, 22, 14 (i.e. when the right hand is placed on the button box and the subject used his index finger the code returned will be 28).
Line 108: Line 104:
This will collect the responses made by the subject during a pre-defined time interval (rt_window). You can also need to define which buttons the subject should press (in this example they are called samekey and diffkey). The codes returned by pressing the buttons are 28, 26, 22, 14 (i.e. when the right hand is placed on the button box and the subject used his index finger the code returned will be 28). The GetResponse() function will by default only return first four button presses. If there is a need to use more than 4 buttons one could use GetResponseExtended() or ReadPIOValue(). The example below uses the latter function and ignores responses 254 and 255, which relate to no-response events.
Line 110: Line 106:
{{{
 tic
 resp=0;
 gotresp=false;
 while toc<rt_window
    if (~gotresp)
       resp=invoke(objSS,'ReadPIOValue');
       if isempty(intersect([255,254],resp))
          gotresp=true;
       end;
    end;
 end;
}}}
Line 112: Line 120:
Line 124: Line 131:
            rt=invoke(objSS,'SSGetTimer')-respstarttime; %or alternatively you can set rt=toc              rt=invoke(objSS,'SSGetTimer')-respstarttime; %or alternatively you can set rt=toc

NB - as of early 2015, the method of using scanner sync in matlab has changed. The new method uses Tibor's ScannerSynchClass rather than Rhodri's MRISync / ScannerSync software,

Using ScannerSync from Matlab - NEW METHOD

Using ScannerSync from Matlab - OLD METHOD

Make sure you have the ScannerSync control installed.

Somewhere near the top of your code, set up ScannerSync & initialise communication with the input-output board (will not work if you're using a machine without the board, e.g., not the mimic or stim delivery machines).

%% SCANNERSYNC
TR=1000; % TR in ms
numdummies=8;

% Create & initialise scanner sync object
objSS=actxserver('MRISync.ScannerSync');  %Create a scanner object
invoke(objSS,'Initialize','') %Initialise the Keithley board and object
invoke(objSS,'SetMSPerSample',2); %Set StartExperiment routines’ sampling

Now, wait for first pulse from scanner. Also, tell ScannerSync the approximate TR.

% ScannerSync - waits for the first pulse, resets timer to 0, sets TR
invoke(objSS,'StartExperiment', double(TR));

Wait for dummies (one less as StartExperiment command above will already have heard a pulse)

for countdown=(numdummies-1):-1:1
    count_text=sprintf('%d', countdown);
  % uncomment the next two if you're using the PsychToolbox
%    DrawFormattedText(window, count_text, 'center', 'center', white);
%    Screen(window, 'Flip');
    invoke(objSS,'SynchroniseExperiment',1,0); %  1= force wait for actual pulse; 0=return this many ms after pulse
end;

In your trial loop, you'll need to spend some of the time listening for pulses

    invoke(objSS,'CheckPulseSynchronyForTime', double(500)); % spend 500 ms listening for any pulses

You should dump out the timing of critical events and the measured TR

    picstarttime=invoke(objSS,'SSGetTimer');
    measuredTR=invoke(objSS,'GetMeasuredTR');

% ...add your own code to write these to your output file

Also, for some designs you may want to occasionally synchronise your trials to the scanner

    invoke(objSS,'SynchroniseExperiment',1,0); %  1= force wait for actual pulse; 0=return this many ms after pulse

Using pretend mode

If you'd like to test code on a machine without the card, you may use a feature of ScannerSync called "pretend mode". To do this:

(1) When in pretend mode, don't do "Initialise", and instead issue a "SetPretendMode" command. So change the first block to something like

pretendmode=1;
% Create & initialise scanner sync object
objSS=actxserver('MRISync.ScannerSync');  %Create a scanner object
if (~pretendmode)
  invoke(objSS,'Initialize','') %Initialise the Keithley board and object
else
  invoke(objSS,'SetPretendMode',1)
end;
invoke(objSS,'SetMSPerSample',2); %Set StartExperiment routines’ sampling

(2) You'll then see a warning message when you get to the "StartExperiment" command, to which you should click "OK". If you're using the PsychToolbox and have already set up the screen, make sure that you only use the HideCursor command after the StartExperiment command, otherwise you won't be able to click OK.

If you would like to use the button box in the practice room of the Scanner building, you will need this code instead to make the button box work:

pretendmode=1;
% Create & initialise scanner sync object
objSS=actxserver('MRISync.ScannerSync');  %Create a scanner object
if (~pretendmode)
  invoke(objSS,'Initialize','') %Initialise the Keithley board and object
else
  invoke(objSS,'SetPretendModeExtended',1,0)
  invoke(objSS,'Initialize','') %Initialise the Keithley board and object
end;
invoke(objSS,'SetMSPerSample',2); %Set StartExperiment routines’ sampling

Collecting Responses

To collect responses in matlab using the button box add a code similar to this:

 tic
 resp=0;
 gotresp=false;
   while toc<rt_window
      if (~gotresp)
         resp=bitand(30,invoke(objSS,'GetResponse'));
         if (resp==samekey || resp==diffkey)
            gotresp=true;
         end;
       end;
    end;

This will collect the responses made by the subject during a pre-defined time interval (rt_window). You can also need to define which buttons the subject should press (in this example they are called samekey and diffkey). The codes returned by pressing the buttons are 28, 26, 22, 14 (i.e. when the right hand is placed on the button box and the subject used his index finger the code returned will be 28).

The GetResponse() function will by default only return first four button presses. If there is a need to use more than 4 buttons one could use GetResponseExtended() or ReadPIOValue(). The example below uses the latter function and ignores responses 254 and 255, which relate to no-response events.

 tic
 resp=0;
 gotresp=false;
 while toc<rt_window
    if (~gotresp)
       resp=invoke(objSS,'ReadPIOValue');
       if isempty(intersect([255,254],resp))
          gotresp=true;
       end;
    end;
 end;

Collecting Response Times

To collect RTs you could try the following:

resp=0;
gotresp=false;
respstarttime=invoke(objSS,'SSGetTimer');
tic
   while toc<rt_window
      if (~gotresp)
         resp=bitand(30,invoke(objSS,'GetResponse'));
         if (resp==samekey || resp==diffkey)
            rt=invoke(objSS,'SSGetTimer')-respstarttime; %or alternatively you can set rt=toc
            gotresp=true;
         end;
       end;
    end;

CbuImaging: ScannerSyncMatlab (last edited 2015-08-28 14:58:08 by RussellThompson)