123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551 |
- function [forces]=ISP_MoBi_sequence(contraction_task, data_subject, volume, forces, bl)
- % the script is identical to ISP_MoBi_sequence_MEP with the exception of no
- % force estimation and only MEP blocks (so there are only TEP blocks).
- % refer to the ISP_MoBi_sequence_MEP for comments
- max_force_left = forces.max_force_left;
- max_force_right = forces.max_force_right;
- 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;
- HideCursor
- %% 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');
- 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');
- io64(ioObj, address ,0);
- %%
- delay_after_TMS = 0.4;
- TMS_extremes = [4.4 6.4]-delay_after_TMS;
- 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);
- %% the systems outputs a "-1/force" function
- % --> set the max of the function to max_force and the min to 0
- % in steps of 500 values of forces (this can be changed)
- x = linspace(1,10,force_steps);
- % produce the shape
- funz_tmp = (-1./x)+1;
- % 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);
- % 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)
- 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);
- hor_alignement = round(misure_schermo(3)*0.5,0);
- ver_alignement = round(misure_schermo(4)*0.25,0);
-
- 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;
- 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);
- %% RUN TIME ACTUAL EXPERIMENT
- Screen('FillRect', window, [0 0 0], misure_schermo);
- [VBL]=Screen(window, 'Flip', ifi, 1);
- tic
- on_spot = 0;
- for tr = 1:num_trials
-
-
- 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.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.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;
-
-
- on_spot = 1;
- Screen('FillRect', window, [0 0 0], misure_schermo);
- Screen('TextSize', window, 80);
- DrawFormattedText(window, '+', 'center','center', [1 1 1]);
-
-
- 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)))
-
-
- 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
|