|
@@ -0,0 +1,607 @@
|
|
|
+function [forces]=ISP_MoBi_sequence(contraction_task, data_subject, volume, forces, bl)
|
|
|
+
|
|
|
+cd 'C:\Users\neuro\Desktop\script_mobi_da_commentare'
|
|
|
+
|
|
|
+sca;
|
|
|
+close all;
|
|
|
+
|
|
|
+
|
|
|
+%%
|
|
|
+
|
|
|
+% consider left hand state
|
|
|
+switch contraction_task{1,2} % force as a proportion of the outer circle...
|
|
|
+
|
|
|
+
|
|
|
+ case 'Contratta'
|
|
|
+
|
|
|
+ LEFT = [0.2 0.4];
|
|
|
+ istruzione_sx = 'Mantieni\nil cerchietto\nverde';
|
|
|
+
|
|
|
+ case 'Rilassata'
|
|
|
+
|
|
|
+ LEFT = [0 0.01];
|
|
|
+ istruzione_sx = 'Rilassa'
|
|
|
+
|
|
|
+end
|
|
|
+
|
|
|
+% consider right hand state
|
|
|
+switch contraction_task{1,3}
|
|
|
+
|
|
|
+
|
|
|
+ case 'Contratta'
|
|
|
+
|
|
|
+ RIGHT = [0.2 0.4];
|
|
|
+ istruzione_dx = 'Mantieni\nil cerchietto\nverde';
|
|
|
+
|
|
|
+ case 'Rilassata'
|
|
|
+
|
|
|
+ RIGHT = [0.0 0.01];
|
|
|
+ istruzione_dx = 'Rilassa'
|
|
|
+
|
|
|
+end
|
|
|
+%% specify trigger number
|
|
|
+switch contraction_task{1,1}
|
|
|
+
|
|
|
+ case 'Mono_AP'
|
|
|
+ TMS_trigger = 3;
|
|
|
+
|
|
|
+ case 'Mono_PA'
|
|
|
+ TMS_trigger = 5;
|
|
|
+
|
|
|
+ case 'Mono_LM'
|
|
|
+ TMS_trigger = 7;
|
|
|
+
|
|
|
+ case 'Bi_PA_contracted'
|
|
|
+ TMS_trigger = 160;
|
|
|
+
|
|
|
+ case 'Bi_AP'
|
|
|
+ TMS_trigger = 130;
|
|
|
+
|
|
|
+ case 'Bi_PA'
|
|
|
+ TMS_trigger = 150;
|
|
|
+
|
|
|
+ case 'Bi_LM'
|
|
|
+ TMS_trigger = 170;
|
|
|
+
|
|
|
+end
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+%%
|
|
|
+% as a proportion to y axis...
|
|
|
+outer_dimension = 0.4;
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+inner_dimensionL = LEFT(1);
|
|
|
+middle_dimensionL = LEFT(2);
|
|
|
+
|
|
|
+
|
|
|
+inner_dimensionR = RIGHT(1);
|
|
|
+middle_dimensionR = RIGHT(2);
|
|
|
+
|
|
|
+
|
|
|
+inner_force_limit_propL = inner_dimensionL;
|
|
|
+outer_force_limit_propL = middle_dimensionL;
|
|
|
+
|
|
|
+inner_force_limit_propR = inner_dimensionR;
|
|
|
+outer_force_limit_propR = middle_dimensionR;
|
|
|
+
|
|
|
+outer_circle_color = [1 1 1];%[0 0 0];%
|
|
|
+middle_circle_color = [0.5 0.5 0.5];
|
|
|
+inner_circle_color = [0 0 0];
|
|
|
+variable_circle_colorL = [0 1 0];
|
|
|
+variable_circle_colorR = [0 1 0];
|
|
|
+variable_circle_thickness = 5;
|
|
|
+
|
|
|
+force_steps = 500;
|
|
|
+
|
|
|
+num_trials = 40;
|
|
|
+
|
|
|
+estimation_time = 10; %secs
|
|
|
+
|
|
|
+time_x_avg = 0.5; % secs
|
|
|
+
|
|
|
+%% DO you want to tinker with small screen?
|
|
|
+tinker = 0;
|
|
|
+
|
|
|
+
|
|
|
+%% SCREEN SETTING
|
|
|
+[window, misure_schermo, screenNum, CenterX, CenterY, ifi] = MoBi_Screen_Settings_Brescia(tinker);
|
|
|
+%MoBi_Screen_Settings_Brescia;
|
|
|
+
|
|
|
+%proporzioni_schermo = misure_schermo(4)/misure_schermo(3);
|
|
|
+
|
|
|
+%%
|
|
|
+delete(instrfindall);
|
|
|
+clear s
|
|
|
+
|
|
|
+%Set up the serial port
|
|
|
+s = serial('COM5'); % cambia su windows
|
|
|
+set(s, 'BaudRate', 115200); % set BaudRate to 115200 (as in Arduino!!!!!)
|
|
|
+
|
|
|
+% open it
|
|
|
+fopen(s);
|
|
|
+WaitSecs(2);
|
|
|
+for d = 1:2
|
|
|
+ MoBi_scrittura(s);
|
|
|
+end
|
|
|
+%%
|
|
|
+[ifi_af, ifi_as, ifi_nf, ifi_ns] = MoBI_frames_Brescia(ifi, ifi);
|
|
|
+
|
|
|
+[onesec_af, onesec_as, onesec_nf, onesec_ns] = MoBI_frames_Brescia(1, ifi);
|
|
|
+
|
|
|
+%% parallel port init
|
|
|
+ioObj = io64;
|
|
|
+status = io64(ioObj);
|
|
|
+
|
|
|
+address = hex2dec('DFB8'); %select LTP1 output port address
|
|
|
+io64(ioObj, address ,0); %set Trigger to zero where it allready should be!!
|
|
|
+
|
|
|
+%%
|
|
|
+
|
|
|
+delay_after_TMS = 0.4;
|
|
|
+TMS_extremes = [4.4 6.4]-delay_after_TMS; %rand(1,1)+1.5
|
|
|
+
|
|
|
+TMS_interval_tmp = (TMS_extremes(2) - TMS_extremes(1))*rand(num_trials,1)+TMS_extremes(1);
|
|
|
+
|
|
|
+[TMS_int_af, TMS_int_as, TMS_int_nf, TMS_int_ns] = MoBI_frames_Brescia(TMS_interval_tmp, ifi);
|
|
|
+
|
|
|
+
|
|
|
+% HideCursor
|
|
|
+
|
|
|
+%% get max force if block 1
|
|
|
+
|
|
|
+if bl == 1
|
|
|
+
|
|
|
+[max_force_left, max_force_right] = ISP_MoBi_get_maximal_force(window, misure_schermo, ifi, s, time_x_avg,estimation_time);
|
|
|
+
|
|
|
+forces = struct;
|
|
|
+forces.max_force_left= max_force_left;
|
|
|
+forces.max_force_right = max_force_right;
|
|
|
+
|
|
|
+else
|
|
|
+
|
|
|
+max_force_left = forces.max_force_left;
|
|
|
+max_force_right = forces.max_force_right;
|
|
|
+
|
|
|
+end
|
|
|
+
|
|
|
+%% the systems outputs a "-1/force" function
|
|
|
+% --> set the max of the function to max_force and the min to 0
|
|
|
+% in steps of 100 values of forces (this can be changed)
|
|
|
+
|
|
|
+x = linspace(1,10,force_steps);%[1:80]
|
|
|
+
|
|
|
+% produce the shape
|
|
|
+funz_tmp = (-1./x)+1; %x
|
|
|
+
|
|
|
+% the shape is morphed so that it goes from 0 to 1 and multuplied by
|
|
|
+% max_force
|
|
|
+funzL = (funz_tmp./(funz_tmp(end)))*max_force_left;
|
|
|
+funzR = (funz_tmp./(funz_tmp(end)))*max_force_right;
|
|
|
+
|
|
|
+% this is the linear function with range [0 max_force] which will be
|
|
|
+% helpful afterwards to linearize the voltage read
|
|
|
+linearizeL = linspace(0, max_force_left, force_steps);
|
|
|
+linearizeR = linspace(0, max_force_right, force_steps);
|
|
|
+
|
|
|
+
|
|
|
+%% SET ALL THE VISUALS on the LEFT
|
|
|
+
|
|
|
+% proportion with respect to the entire screen
|
|
|
+set_proportion_of_diameter_outer_circleL = outer_dimension;
|
|
|
+prop_diameter_outer_circleL = set_proportion_of_diameter_outer_circleL;
|
|
|
+
|
|
|
+% transform proportions to actual pixels --> we get dimaeter of outer
|
|
|
+% circle in pixels
|
|
|
+dimensions_outer_circleL = MoBi_prop2dim(misure_schermo, 0, prop_diameter_outer_circleL);
|
|
|
+
|
|
|
+% same procedure for inner and middle circle calculated on the basis of the outer
|
|
|
+% circle
|
|
|
+prop_diameter_inner_circleL = inner_dimensionL*prop_diameter_outer_circleL;
|
|
|
+dimensions_inner_circleL = MoBi_prop2dim(misure_schermo, 0, prop_diameter_inner_circleL);
|
|
|
+
|
|
|
+prop_diameter_middle_circleL = middle_dimensionL*prop_diameter_outer_circleL;
|
|
|
+dimensions_middle_circleL = MoBi_prop2dim(misure_schermo, 0, prop_diameter_middle_circleL);
|
|
|
+
|
|
|
+%% generate a structure for the LEFT circle with the features of the circle as fields
|
|
|
+
|
|
|
+% we have two objsect now...place the left one on the first quarter of the
|
|
|
+% screen length, the other on the last quarter
|
|
|
+
|
|
|
+first_quarter = 3*misure_schermo(3)/8;
|
|
|
+last_quarter = 5*misure_schermo(3)/8;
|
|
|
+
|
|
|
+% ...color
|
|
|
+ObL.outer_circle.color = outer_circle_color;
|
|
|
+% ...diameter
|
|
|
+ObL.outer_circle.dimension = [0 0 dimensions_outer_circleL(2) dimensions_outer_circleL(2)]
|
|
|
+% center position on the screen
|
|
|
+baseRect_outer = [ObL.outer_circle.dimension];
|
|
|
+
|
|
|
+% place in the first quarter
|
|
|
+ObL.outer_circle.dimension = CenterRectOnPoint(baseRect_outer, first_quarter, misure_schermo(4)/2);% da che cosa dipendono questi numeri???
|
|
|
+
|
|
|
+
|
|
|
+% same goes for the other circles
|
|
|
+ObL.inner_circle.color = inner_circle_color;
|
|
|
+ObL.inner_circle.dimension = [0 0 dimensions_inner_circleL(2) dimensions_inner_circleL(2)]
|
|
|
+baseRect_inner = [ObL.inner_circle.dimension];
|
|
|
+
|
|
|
+% place in the first quarter
|
|
|
+ObL.inner_circle.dimension = CenterRectOnPoint(baseRect_inner, first_quarter, misure_schermo(4)/2);
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ObL.middle_circle.color = middle_circle_color;
|
|
|
+ObL.middle_circle.dimension = [0 0 dimensions_middle_circleL(2) dimensions_middle_circleL(2)]
|
|
|
+baseRect_middle = [ObL.middle_circle.dimension];
|
|
|
+
|
|
|
+% place in the first quarter
|
|
|
+ObL.middle_circle.dimension = CenterRectOnPoint(baseRect_middle, first_quarter, misure_schermo(4)/2);
|
|
|
+
|
|
|
+
|
|
|
+%% SET ALL THE VISUALS on the RIGHT
|
|
|
+
|
|
|
+% proportion with respect to the entire screen
|
|
|
+set_proportion_of_diameter_outer_circleR = outer_dimension;
|
|
|
+prop_diameter_outer_circleR = [set_proportion_of_diameter_outer_circleR];
|
|
|
+
|
|
|
+% transform proportions to actual pixels --> we get dimaeter of outer
|
|
|
+% circle in pixels
|
|
|
+dimensions_outer_circleR = MoBi_prop2dim(misure_schermo, 0, prop_diameter_outer_circleR);
|
|
|
+
|
|
|
+% same procedure for inner and middle circle calculated on the basis of the outer
|
|
|
+% circle
|
|
|
+prop_diameter_inner_circleR = inner_dimensionR*prop_diameter_outer_circleR;
|
|
|
+dimensions_inner_circleR = MoBi_prop2dim(misure_schermo, 0, prop_diameter_inner_circleR);
|
|
|
+
|
|
|
+prop_diameter_middle_circleR = middle_dimensionR*prop_diameter_outer_circleR;
|
|
|
+dimensions_middle_circleR = MoBi_prop2dim(misure_schermo, 0, prop_diameter_middle_circleR);
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+%% generate a structure for the RIGHT circle with the features of the circle as fields
|
|
|
+
|
|
|
+% ...color
|
|
|
+ObR.outer_circle.color = outer_circle_color;
|
|
|
+% ...diameter
|
|
|
+ObR.outer_circle.dimension = [0 0 dimensions_outer_circleR(2) dimensions_outer_circleR(2)];
|
|
|
+% center position on the screen;
|
|
|
+baseRect_outer = [ObR.outer_circle.dimension];
|
|
|
+
|
|
|
+% place in the first quarter
|
|
|
+ObR.outer_circle.dimension = CenterRectOnPoint(baseRect_outer, last_quarter, misure_schermo(4)/2);% da che cosa dipendono questi numeri???
|
|
|
+
|
|
|
+
|
|
|
+% same goes for the other circles
|
|
|
+ObR.inner_circle.color = inner_circle_color;
|
|
|
+ObR.inner_circle.dimension = [0 0 dimensions_inner_circleR(2) dimensions_inner_circleR(2)]
|
|
|
+baseRect_inner = [ObR.inner_circle.dimension];
|
|
|
+
|
|
|
+% place in the last quarter
|
|
|
+ObR.inner_circle.dimension = CenterRectOnPoint(baseRect_inner, last_quarter, misure_schermo(4)/2);
|
|
|
+
|
|
|
+ObR.middle_circle.color = middle_circle_color;
|
|
|
+ObR.middle_circle.dimension = [0 0 dimensions_middle_circleR(2) dimensions_middle_circleR(2)]
|
|
|
+baseRect_middle = [ObR.middle_circle.dimension];
|
|
|
+
|
|
|
+% place in the last quarter
|
|
|
+ObR.middle_circle.dimension = CenterRectOnPoint(baseRect_middle, last_quarter, misure_schermo(4)/2);
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+%% we also have a black background. let's treat it as a structre as well.
|
|
|
+Bk.color = [0 0 0];
|
|
|
+Bk.dimension = misure_schermo;
|
|
|
+
|
|
|
+%% resolution setting:
|
|
|
+% every time participant presses, read values change. here we set the boundary values to which a variable circle will change its diameter based on the pressure produced
|
|
|
+
|
|
|
+% create a vector from 0 to diameter of outer circle in steps of
|
|
|
+% length(x)...100 is a good number for it
|
|
|
+diameter_values_nonscaled_tmp = linspace(0, dimensions_outer_circleL(2), length(x));
|
|
|
+
|
|
|
+
|
|
|
+% in case participants press more than what they did in the max_force
|
|
|
+% evaluation, values bigger that outer_circle diameter are added, in order
|
|
|
+% not to get errors.
|
|
|
+% It should not happen though because it would mean the max_force
|
|
|
+% estimatimation was performed in a shitty way.
|
|
|
+diameter_values_nonscaled = [diameter_values_nonscaled_tmp ...
|
|
|
+ diameter_values_nonscaled_tmp(end)+[1:100].*diff(diameter_values_nonscaled_tmp(1:2))];
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+%% INSTRUCTIONS FOR the researcher
|
|
|
+Screen('FillRect', window, Bk.color, Bk.dimension);
|
|
|
+Screen('TextSize', window, 25);
|
|
|
+
|
|
|
+
|
|
|
+% switch hem_task{1,1}
|
|
|
+%
|
|
|
+% case 'Emisfero_Sx'
|
|
|
+ hor_alignement = round(misure_schermo(3)*0.5,0);
|
|
|
+ ver_alignement = round(misure_schermo(4)*0.25,0);
|
|
|
+
|
|
|
+% case 'Emisfero_Dx'
|
|
|
+% hor_alignement = round(misure_schermo(3)*0.75,0);
|
|
|
+% ver_alignement = round(misure_schermo(4)*0.25,0);
|
|
|
+%
|
|
|
+% end
|
|
|
+
|
|
|
+TMS_cond = contraction_task{1,1};
|
|
|
+
|
|
|
+DrawFormattedText(window,TMS_cond, hor_alignement,...
|
|
|
+ ver_alignement, [1 1 1]);
|
|
|
+
|
|
|
+clear hor_alignement ver_alignement
|
|
|
+
|
|
|
+testo_sx = contraction_task{1,2};
|
|
|
+
|
|
|
+
|
|
|
+ hor_alignement = round(misure_schermo(3)*0.25,0);
|
|
|
+ ver_alignement = round(misure_schermo(4)*0.75,0);
|
|
|
+
|
|
|
+
|
|
|
+ DrawFormattedText(window,testo_sx, hor_alignement,...
|
|
|
+ ver_alignement, [1 1 1]);
|
|
|
+
|
|
|
+ clear hor_alignement ver_alignement
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+testo_dx = contraction_task{1,3};
|
|
|
+
|
|
|
+
|
|
|
+ hor_alignement = round(misure_schermo(3)*0.75,0);
|
|
|
+ ver_alignement = round(misure_schermo(4)*0.75,0);
|
|
|
+
|
|
|
+
|
|
|
+ DrawFormattedText(window,testo_dx, hor_alignement,...
|
|
|
+ ver_alignement, [1 1 1]);
|
|
|
+
|
|
|
+ clear hor_alignement ver_alignement
|
|
|
+
|
|
|
+[VBL]=Screen(window, 'Flip', ifi, 1);
|
|
|
+
|
|
|
+% wait for keyboard press
|
|
|
+WaitSecs(2)
|
|
|
+
|
|
|
+%%
|
|
|
+ while ~KbCheck
|
|
|
+
|
|
|
+ end
|
|
|
+
|
|
|
+%%
|
|
|
+%% start noise
|
|
|
+
|
|
|
+
|
|
|
+[audiodata, infreq] = psychwavread('AirCool_Magstim_48000.wav');
|
|
|
+
|
|
|
+noise_seconds = 60*5; % ten minutes
|
|
|
+
|
|
|
+noise_short = audiodata(1:infreq*noise_seconds)';
|
|
|
+
|
|
|
+pasound2 = PsychPortAudio('Open', []);
|
|
|
+
|
|
|
+sound2 = [noise_short; noise_short];
|
|
|
+
|
|
|
+PsychPortAudio('Volume', pasound2, volume);
|
|
|
+
|
|
|
+PsychPortAudio('FillBuffer', pasound2, sound2);
|
|
|
+
|
|
|
+noise_ts = PsychPortAudio('Start',pasound2, 1, 1);
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+%% linearization of the force:
|
|
|
+% the response of the pressure sensor is not linear
|
|
|
+% the decrease of resistance is not linearly proportional to the force
|
|
|
+% applied to it
|
|
|
+
|
|
|
+
|
|
|
+% so we want to map the non-linear (-1/force) output across the fR to a
|
|
|
+% linear one, this way a fixed amount of force increase will increase the read value of a fixed interval independently of the initial force applied
|
|
|
+
|
|
|
+% the linearization mapping will be applied while acquiring thanks to the
|
|
|
+% following mapping
|
|
|
+
|
|
|
+% funz is the non linear output from the reading
|
|
|
+% linearize = linspace(0, max_force, force_steps);
|
|
|
+%
|
|
|
+% idx = find(force<=funz, 1, 'first');
|
|
|
+%
|
|
|
+% force_lin = linearize(idx);
|
|
|
+
|
|
|
+
|
|
|
+%% EXPERIMENT
|
|
|
+Screen('FillRect', window, [0 0 0], misure_schermo);
|
|
|
+[VBL]=Screen(window, 'Flip', ifi, 1);
|
|
|
+tic
|
|
|
+on_spot = 0;
|
|
|
+for tr = 1:num_trials
|
|
|
+
|
|
|
+% if (tr == round(num_trials/3)) || (tr == 2*round(num_trials/3))
|
|
|
+%
|
|
|
+% Screen('FillRect', window, Bk.color, Bk.dimension);
|
|
|
+% Screen('TextSize', window, 25);
|
|
|
+% DrawFormattedText(window, 'pause', 'center',...
|
|
|
+% 'center', [1 1 1]);
|
|
|
+% [VBL]=Screen(window, 'Flip', ifi,1);
|
|
|
+%
|
|
|
+% while ~KbCheck
|
|
|
+% end
|
|
|
+%
|
|
|
+%
|
|
|
+% end
|
|
|
+
|
|
|
+ i = 0;
|
|
|
+ while 1
|
|
|
+
|
|
|
+ % read from serial port what arduino has written
|
|
|
+ force_tmp = MoBi_scrittura(s);
|
|
|
+
|
|
|
+ % split the 3 values that are read from the three pins in arduino
|
|
|
+ force_tmp2 = (strsplit(force_tmp, '_'));
|
|
|
+
|
|
|
+ % GET INFO ONLY FROM THE A0 PIN, which is the first read
|
|
|
+ force_tmpL = str2double(force_tmp2{1});
|
|
|
+ force_tmpR = str2double(force_tmp2{2});
|
|
|
+
|
|
|
+ % force linearization.
|
|
|
+ [linear_forceL idxL] = MoBi_linearize_force(force_tmpL, linearizeL, funzL);
|
|
|
+ [linear_forceR idxR] = MoBi_linearize_force(force_tmpR, linearizeR, funzR);
|
|
|
+
|
|
|
+ %%
|
|
|
+ diameter_valuesL = diameter_values_nonscaled(idxL);
|
|
|
+ diameter_valuesR = diameter_values_nonscaled(idxR);
|
|
|
+
|
|
|
+ if on_spot == 0
|
|
|
+ % draw left side circles in background
|
|
|
+ ObL.variable_circle.color = variable_circle_colorL;
|
|
|
+ ObL.variable_circle.dimension = [0 0 diameter_valuesL diameter_valuesL];
|
|
|
+ baseRect_variable = [ObL.variable_circle.dimension];
|
|
|
+ ObL.variable_circle.dimension = CenterRectOnPoint(baseRect_variable, first_quarter, misure_schermo(4)/2);
|
|
|
+
|
|
|
+ Screen('FrameOval', window, ObL.outer_circle.color, ObL.outer_circle.dimension);
|
|
|
+ Screen('FillOval', window, ObL.middle_circle.color, ObL.middle_circle.dimension);
|
|
|
+ % Screen('FillOval', window, ObL.variable_circle.color, ObL.variable_circle.dimension);
|
|
|
+ Screen('FillOval', window, ObL.inner_circle.color, ObL.inner_circle.dimension);
|
|
|
+ Screen('FrameOval', window, ObL.variable_circle.color, ObL.variable_circle.dimension, variable_circle_thickness);
|
|
|
+
|
|
|
+ % draw right side circles in background
|
|
|
+ ObR.variable_circle.color = variable_circle_colorR;
|
|
|
+ ObR.variable_circle.dimension = [0 0 diameter_valuesR diameter_valuesR];
|
|
|
+ baseRect_variable = [ObR.variable_circle.dimension];
|
|
|
+ ObR.variable_circle.dimension = CenterRectOnPoint(baseRect_variable, last_quarter, misure_schermo(4)/2);
|
|
|
+
|
|
|
+ Screen('FrameOval', window, ObR.outer_circle.color, ObR.outer_circle.dimension);
|
|
|
+ Screen('FillOval', window, ObR.middle_circle.color, ObR.middle_circle.dimension);
|
|
|
+ % Screen('FillOval', window, ObR.variable_circle.color, ObR.variable_circle.dimension);
|
|
|
+ Screen('FillOval', window, ObR.inner_circle.color, ObR.inner_circle.dimension);
|
|
|
+ Screen('FrameOval', window, ObR.variable_circle.color, ObR.variable_circle.dimension, variable_circle_thickness);
|
|
|
+
|
|
|
+
|
|
|
+ Screen('TextSize', window, 80);
|
|
|
+ DrawFormattedText(window, '+', 'center','center', [1 1 1]);
|
|
|
+ else
|
|
|
+ Screen('FillRect', window, [0 0 0], misure_schermo);
|
|
|
+ Screen('TextSize', window, 80);
|
|
|
+ DrawFormattedText(window, '+', 'center','center', [1 1 1]);
|
|
|
+ end
|
|
|
+
|
|
|
+
|
|
|
+ % flip
|
|
|
+ [VBL] = Screen(window, 'Flip', VBL+ifi_as);
|
|
|
+
|
|
|
+ sprintf( '%f_%f_%f____%f_%f_%f', inner_force_limit_propL*max_force_left, linear_forceL, outer_force_limit_propL*max_force_left,...
|
|
|
+ inner_force_limit_propR*max_force_right, linear_forceR, outer_force_limit_propR*max_force_right)
|
|
|
+
|
|
|
+ %% check force range for TMS
|
|
|
+ if (linear_forceL >= inner_force_limit_propL*max_force_left) && (linear_forceL <= outer_force_limit_propL*max_force_left)...
|
|
|
+ && (linear_forceR >= inner_force_limit_propR*max_force_right) && (linear_forceR <= outer_force_limit_propR*max_force_right)
|
|
|
+
|
|
|
+ i= i+1;
|
|
|
+
|
|
|
+ % this way it does not blink if the position is lost
|
|
|
+ % if i<20
|
|
|
+ % on_spot = 0;
|
|
|
+ % else
|
|
|
+ on_spot = 1;
|
|
|
+ Screen('FillRect', window, [0 0 0], misure_schermo);
|
|
|
+ Screen('TextSize', window, 80);
|
|
|
+ DrawFormattedText(window, '+', 'center','center', [1 1 1]);
|
|
|
+ %
|
|
|
+ % end
|
|
|
+
|
|
|
+ else % ... if force is out of range
|
|
|
+ i = 0;
|
|
|
+ on_spot = 0;
|
|
|
+
|
|
|
+
|
|
|
+ % change colors of the circle that is out
|
|
|
+ if (linear_forceL <= inner_force_limit_propL*max_force_left) || (linear_forceL >= outer_force_limit_propL*max_force_left)...
|
|
|
+
|
|
|
+ variable_circle_colorL = [1 0 0];
|
|
|
+ else
|
|
|
+ variable_circle_colorL = [0 1 0];
|
|
|
+ end
|
|
|
+
|
|
|
+ if (linear_forceR <= inner_force_limit_propR*max_force_right) || (linear_forceR >= outer_force_limit_propR*max_force_right)
|
|
|
+
|
|
|
+ variable_circle_colorR = [1 0 0];
|
|
|
+ else
|
|
|
+ variable_circle_colorR = [0 1 0];
|
|
|
+ end
|
|
|
+ end
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ % in case i is equal or greater than than the frames to be waited
|
|
|
+ % for TMS to be delivered, then deliver TMS
|
|
|
+ if i >= TMS_int_nf(tr)
|
|
|
+
|
|
|
+ can_i_trigger = 1;
|
|
|
+
|
|
|
+ % function implementing also trigger value
|
|
|
+ MoBi_Trigger(ioObj,address,TMS_trigger, can_i_trigger);
|
|
|
+
|
|
|
+ can_i_trigger = 0;
|
|
|
+
|
|
|
+ TR.TMS_timing(tr) = VBL;
|
|
|
+ TR.i(tr) = i;
|
|
|
+ TR.ns(tr) = TMS_int_ns(tr);
|
|
|
+ TR.nf(tr) = TMS_int_nf(tr);
|
|
|
+ TR.tictoc(tr) = toc;
|
|
|
+ disp(strcat('TMS', '_', num2str(tr)))
|
|
|
+
|
|
|
+ % aspetta in ogni caso cosi non ci sono potenziali che
|
|
|
+ % interferiscono con il TEP
|
|
|
+ WaitSecs(delay_after_TMS)
|
|
|
+
|
|
|
+ % break the while loop and start another trial
|
|
|
+ break
|
|
|
+ end
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ end
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+end
|
|
|
+
|
|
|
+sca
|
|
|
+
|
|
|
+% forces = struct;
|
|
|
+% forces.max_force_left = max_force_left;
|
|
|
+% forces.max_force_right = max_force_right;
|
|
|
+% forces.sbj = sbj;
|
|
|
+% forces.order = ordine
|
|
|
+% forces.block = block;
|
|
|
+% forces.within_ordine = row_tabella;
|
|
|
+% forces.session = blocco;
|
|
|
+
|
|
|
+PsychPortAudio('Stop', pasound2,0);
|
|
|
+PsychPortAudio('Close');
|
|
|
+clear audiodata sound2 noise_short pasound2 sound2
|
|
|
+
|
|
|
+save(data_subject)
|
|
|
+
|
|
|
+end
|
|
|
+
|