4
\$\begingroup\$

I have written the code below for the following experiment:

  • Subjects get simultaneous stimulation of left and right thumb and have to tell which one was stimulated "stronger" (with higher intensity, i.e. with higher amplitude of the sine wave we output)
  • One of the two signals does not change, while the other signal is always a percentage of the former (so we have for one thumb S1 and for the other percentage*S1. S1 has always the same amplitude, but "percentage" changes depending on how the participant answers). Which thumb gets which signal is always randomized.
  • If the subject gives three correct answers in a row, the percentage will be decreased. After one wrong answer it will be already increased.

You don't have to look at the more "technical" part (definition of the signal etc.) but I would be super glad if you could check the logic of the experiment which is mostly in the part coming after "%%Staircase" and a bit more than 100 lines. I have seen it a bit too often and feel that I might miss out on things others might see.

clear all
close all



Fields = {'Subject ID',... 
    'Handedness (0=left, 1 = right)',... 
    'Testhand (0=left, 1 = right, 2 = both)',... 
    'Number of Trials',... 
    'Trial Duration',... 
    'Break Duration',... 
    'Stimulation Frequency',...
    'Carrier Frequency',...
    'Fixed Intensity [V]',...
    'Percentage'};

Defaults = {'',...
    '1',...
    '2',...
    '20',...
    '2',...
    '2',...
    '21',...
    '200',...
    '0.2',...
    '0.3'};

Settings = inputdlg(Fields, 'Amplitude Strength Detection', 1, Defaults);


%% Step 1) Get settings & construct signal

timestamp=datestr(now, 'yyyymmdd-HHMM');

nTrials = str2double(Settings(strcmp(Fields, 'Number of Trials')));
stimDur = str2double(Settings(strcmp(Fields, 'Trial Duration')));
pauseDur = str2double(Settings(strcmp(Fields, 'Break Duration')));
SampFreq = 10000; %Sampling Frequency (needed for d->a)
CarrFreq = str2double(Settings(strcmp(Fields, 'Carrier Frequency')));
StimFreq = str2double(Settings(strcmp(Fields, 'Stimulation Frequency')));
FixedInt = str2double(Settings(strcmp(Fields, 'Fixed Intensity [V]')));
InitPerc = str2double(Settings(strcmp(Fields, 'Percentage')));

Settings(strcmp(Fields, 'Subject ID'));

% Timepoints of stimulation according to Sampling Frequency
t = linspace(0,stimDur, SampFreq*stimDur);

% File management
savepath = pwd;
filename = [savepath filesep 'AmpStrengthDetection_' char(Settings(strcmp(Fields, 'Subject ID'))) '_'  num2str(StimFreq)  'Hz_' timestamp '.mat'];


%Signals
am = 1; %amplitude modulation depth (0 = sin wave of Carrier Frequency, 1 = modulation to 0)
as1 = 1+am*sin(2*pi*StimFreq*t);
cs1 = sin(2*pi*CarrFreq*t);

% Signal for first hand
stimSig1 = cs1.*as1;
maxInt=max(stimSig1);
stimSig1 = FixedInt*(stimSig1/maxInt); 


%Initialize DAQ 

dev = 'cDAQ1Mod1';
vendor = 'ni';

S = daq.createSession(vendor);  %Create new session obj //NOTE: UPPERCASE S = DAQ SESSION OBJ, LOWERCASE s = SERIAL OBJ!!!!
S.Rate = SampFreq; %Set sampling rate
S.addAnalogOutputChannel(dev, 'ao0', 'Voltage');  %Add output channel
S.addAnalogOutputChannel(dev, 'ao1', 'Voltage');
S.IsContinuous = false; 


%% Step 2) Measure threshold


% default that left hand is stimulated with constant signal
ConstLeft = true;

% Default values for staircase variables 
staircaseLeft = [];
staircaseRight =[];
nLeft = 1;
nRight = 1;

nCorLeft=0;
nCorRight=0;

lowerLeft = false;
lowerRight = false;
raiseLeft = false;
raiseRight = false;

% How much to change InitPerc
stepSizeUp=0.05;
stepSizeDown = stepSizeUp*0.7393; 
rng('shuffle');


%% Staircase

for m = 1:nTrials


% Randomly assign constant signal to left or right hand
% The other signal is a percentage of this signal


stimLeft = [stimSig1]'; 
stimRight = [stimSig1]'; 



% Normalization of the signal
a = rand;
if a < 0.5

stimRight(:,1) = FixedInt*(stimRight(:,1)/max(stimRight(:,1)));
stimRight(end,:) =0;

stimLeft(:,1) = InitPerc*FixedInt*(stimLeft(:,1)/max(stimLeft(:,1)));
stimLeft(end,:)=0;

else

stimRight(:,1) = InitPerc*FixedInt*(stimRight(:,1)/max(stimRight(:,1)));
stimRight(end,:) =0;

stimLeft(:,1) = FixedInt*(stimLeft(:,1)/max(stimLeft(:,1)));
stimLeft(end,:)=0;

end


outSig = [stimLeft, stimRight];


    %fwrite(s,10)
    stopBreakAt = GetSecs+pauseDur;
    outSig(isnan(outSig)) = 0.005;
    S.queueOutputData(outSig);
    now=GetSecs;
    while now<stopBreakAt;
        now=GetSecs;
    end
    %fwrite(s,60) %Stimulation marker = 60
    stopStimAt = GetSecs+stimDur+0.5;
    %S.startBackground();
    S.startForeground();
    now = GetSecs();
    while now<stopStimAt %Endless loop to wait for stim
        now = GetSecs();
    end
    %S.stop();

    disp('Left or Right?')
    KbQueueCreate;
    KbQueueStart;
    pressed=0;
    while ~pressed
        [pressed, firstPress] = KbQueueCheck;
        answer=find(firstPress,1);
        disp(KbName(answer));
    end
    KbQueueStop;
    KbQueueRelease;

    if (ConstLeft & answer == 37)
        staircaseLeft(nLeft) = InitPerc;
        nLeft = nLeft + 1;
        nCorLeft = nCorLeft+1;
        if (nCorLeft == 3)
            lowerLeft = true;
            nCorLeft = 0;
        end  
    end

    if (ConstLeft & answer ~= 37)
        staircaseLeft(nLeft) = InitPerc;
        nLeft = nLeft + 1;
        nCorLeft = 0;
        raiseLeft = true;
    end

    if (~ConstLeft & answer == 39)
        staircaseRight(nRight) = InitPerc;
        nRight = nRight + 1;
        nCorRight = nCorRight+1;
        if (nCorRight == 3)
            lowerRight = true;
            nCorRight = 0;
        end
    end

    if (~ConstLeft & answer ~= 39)
        staircaseRight(nRight) = InitPerc;
        nRight = nRight + 1;
        nCorRight = 0;
        raiseRight = true;
    end

    % Change the percentage value InitPerc depending of answers given:

    % Raise InitPerc if answers wrong

    if (raiseLeft | raiseRight)
        InitPerc = InitPerc + stepSizeUp

        raiseLeft = false;
        raiseRight = false;
    end

     % Lower InitPerc if answers three consecutive times right

    if (lowerLeft | lowerRight)
        InitPerc = InitPerc - stepSizeDown;

        lowerLeft = false;
        lowerRight = false;
    end


    disp(['InitPerc: ' num2str(InitPerc)]);


end

leftThr = mean(staircaseLeft(1:end));
rightThr = mean(staircaseRight(1:end));


save(filename, 'Fields', 'Settings', 'leftThr', 'rightThr', 'staircaseLeft', 'staircaseRight');

disp('End of Experiment');
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.