You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
515 lines
17 KiB
515 lines
17 KiB
function ContMatch_session_Rivalry(subName,meanLum,Bckg_Chro,AdaptTime,curr_cond) |
|
|
|
try |
|
assignin('base','Stop_Press',0)% this works for the STOP experiment button |
|
|
|
commandwindow; % open this, and the cursor will appear there |
|
% Check that Psychtoolbox is properly installed, switch to unified KbName's |
|
% across operating systems, and switch color range to normalized 0 - 1 range: |
|
PsychDefaultSetup(2); |
|
|
|
%% Start Experiment |
|
|
|
%a = cd; |
|
theDate = fix(clock); |
|
mainDir = '/Users/mike/Documents/AfterImage/002 After Image GUI Project'; |
|
locOutDir = ['/Users/mike/Documents/AfterimageOutputs/']; |
|
saveFile = sprintf('%s%s_ContMatch.mat', locOutDir, subName); |
|
|
|
%% Color information, load hfp data and color calibration |
|
|
|
hfpFile = sprintf('%s%sHFP', locOutDir, subName); |
|
load([hfpFile,'.mat']); |
|
hfpRG = rg_avg |
|
hfpBG = bg_avg |
|
|
|
% hfpRG = .89; |
|
% hfpBG = 1 ; |
|
|
|
%% Load previous matched contrast |
|
|
|
name = sprintf('%s%s_ContMatch.mat', locOutDir, subName); |
|
if exist(name, 'file') == 2 |
|
|
|
load(name) |
|
|
|
% Prev_l_cont_match = l_cont_match; |
|
l_cont_match = []; |
|
% Prev_lum_cont_match = lum_cont_match; |
|
lum_cont_match = []; |
|
% Prev_lumMod_match = lumMod_match; |
|
lumMod_match = []; |
|
|
|
|
|
|
|
else |
|
|
|
Prev_l_cont_match = []; |
|
Prev_lum_cont_match = []; |
|
Prev_lumMod_match = []; |
|
|
|
end |
|
|
|
|
|
|
|
|
|
%% |
|
%cd(a); % return to folder where the program is |
|
% Calib_Dire = cd('/Users/clemente/Dropbox/Luminotecnia/2017/Chicago Lab files/2 Experiments/Color AfterImage_Exp_Room_150/2nd/1 Programs/001 After Image GUI Project'); |
|
load([mainDir,'/colorCalFile1.mat']); |
|
fprintf('\nLast calibration was %s\n', describe.date); |
|
pix = pix/1001; |
|
maxLum = 20; %cd/m^2 |
|
|
|
lumMod_initial = [.6 .7 .8 1 ]; |
|
|
|
lCont_initial = [0.02 0.026 0.034 .04]; |
|
|
|
|
|
sCont = [.35 .5 .65 .8]; |
|
% sCont = [.5 .5 .5 .5]; |
|
|
|
nCont = length(sCont); |
|
|
|
% white = [.665 1]; |
|
blackLut = [0 0 0]; |
|
redLut = [.8 0 0]; |
|
|
|
% % Bckg_Chro = [.665 1.353 |
|
% % .665 .647 |
|
% % .647 1 |
|
% % .683 1]; % 4 rows X 2 columns |
|
|
|
|
|
%% set up psych toolbox |
|
%set up 10 bit color |
|
PsychImaging('PrepareConfiguration'); |
|
%PsychImaging('AddTask', 'General', 'EnableNative10BitFrameBuffer',1); %the 0 is turn off dithering? |
|
expScreen = 1; |
|
%create white LUT |
|
% % % wLMS(1,1) = white(1,1)*maxLum; |
|
% % % wLMS(1,2) = (1-white(1,1))*maxLum; |
|
% % % wLMS(1,3) = white(1,2)*maxLum; |
|
% % % wXYZ(1,:) = LMS_to_XYZ(wLMS(1,:)); |
|
% % % wRGB(1,:) = XYZ_to_RGB(wXYZ(1,:), maxPhosXYZ); |
|
% % % wRGB(1,1) = pix(dsearchn(redProp(:), wRGB(1,1)))*hfpRG; |
|
% % % wRGB(1,2) = pix(dsearchn(grnProp(:), wRGB(1,2))); |
|
% % % wRGB(1,3) = pix(dsearchn(blueProp(:), wRGB(1,3)))*hfpBG; |
|
|
|
[window, windowRect] = PsychImaging('OpenWindow', expScreen, [0 0 0], [], [], []); % |
|
%Screen('OpenWindow',0, [0 0 0]); %makes main screen dark |
|
%PsychImaging('OpenWindow', expScreen, wRGB); |
|
[xcent,ycent] = RectCenter(windowRect); |
|
center = [xcent ycent]; |
|
[xWinSize,~] = Screen('WindowSize',window); |
|
|
|
%% TIMING |
|
%find frames per second |
|
ifi = Screen('GetFlipInterval', window);% Measure the vertical refresh rate of the monitor |
|
topPriorityLevel = MaxPriority(window);% Retreive the maximum priority number |
|
% % % % numSecs = 16; %in seconds, total presentation time |
|
hfpFreq = 4.6; hfpPeriod = 1/hfpFreq; |
|
numSecs = hfpPeriod; %in seconds, total presentation time |
|
framesPerSec = round(1/ifi); |
|
nFrames = numSecs * framesPerSec; |
|
|
|
% waitframes = floor(framesPerSec/hfpFreq); %number of frames to wait between refresh |
|
nFrames = round(hfpPeriod /ifi) ; |
|
% % % % waitframes = 1; %number of frames to wait between refresh |
|
waitframes = 1; %number of frames to wait between refresh |
|
|
|
%% Stimulus Size Parameters |
|
circleDeg = 3.6; |
|
clockPt = 0.1; |
|
|
|
% code assumes 1 pixel = 1 arc min |
|
pixPerDeg = 35; %at a distance of 57 cm |
|
circlePix = circleDeg*pixPerDeg; |
|
clockPix = clockPt*pixPerDeg; |
|
|
|
tstcircle = [xcent - circlePix/2 ycent - circlePix/2 xcent + circlePix/2 ycent + circlePix/2]; |
|
rhtXCircleCenter = xWinSize/4; |
|
lftXCircleCenter = xWinSize-xWinSize/4; |
|
tstCircleLeft = [lftXCircleCenter - circlePix/2 ycent - circlePix/2 lftXCircleCenter + circlePix/2 ycent + circlePix/2]; |
|
tstCircleRight = [rhtXCircleCenter - circlePix/2 ycent - circlePix/2 rhtXCircleCenter + circlePix/2 ycent + circlePix/2]; |
|
|
|
% Specs for the border frame |
|
frameSize = 60; |
|
frameWidth = 5; |
|
frameCircleLeft = [tstCircleLeft(1)-frameSize tstCircleLeft(2)-frameSize tstCircleLeft(3)+frameSize tstCircleLeft(4)+frameSize]; |
|
frameCircleRight = [tstCircleRight(1)-frameSize tstCircleRight(2)-frameSize tstCircleRight(3)+frameSize tstCircleRight(4)+frameSize]; |
|
|
|
WaitSecs(1); |
|
|
|
%run experiment |
|
Priority(topPriorityLevel); |
|
|
|
vbl = Screen('Flip', window); |
|
|
|
|
|
|
|
|
|
%%///////////////////////////////////////////////////////////////////////// |
|
%%/ TRIALS |
|
%%///////////////////////////////////////////////////////////////////////// |
|
|
|
stepSize_l = 0.0005; |
|
stepSize_lum = 0.01; |
|
order = randi(1); |
|
count = 0; |
|
|
|
nRep = 3; % in this case is always three |
|
|
|
for iChro = 1:size(Bckg_Chro,1) |
|
|
|
wLMS(1,1) = Bckg_Chro(iChro,1)*maxLum; |
|
wLMS(1,2) = (1-Bckg_Chro(iChro,1))*maxLum; |
|
wLMS(1,3) = Bckg_Chro(iChro,2)*maxLum; |
|
wXYZ(1,:) = LMS_to_XYZ(wLMS(1,:)); |
|
wRGB(1,:) = XYZ_to_RGB(wXYZ(1,:), maxPhosXYZ); |
|
wRGB(1,1) = pix(dsearchn(redProp(:), wRGB(1,1)))*hfpRG; |
|
wRGB(1,2) = pix(dsearchn(grnProp(:), wRGB(1,2))); |
|
wRGB(1,3) = pix(dsearchn(blueProp(:), wRGB(1,3)))*hfpBG; |
|
|
|
Screen('FillRect', window, wRGB); |
|
Screen('Flip',window) |
|
WaitSecs(AdaptTime) |
|
|
|
for iaxis = curr_cond(1):curr_cond(end); % 1 means lCont and 2 means lumCont |
|
for icont = 1:nCont % number of contrast to match |
|
for irep = 1:nRep % |
|
|
|
FlushEvents('mouseDown','keyDown'); |
|
|
|
order = de2bi(count) |
|
order = order(1); %use the last digit of the binary number (that is the first to matlab) so it switch between 0 and 1 |
|
|
|
if iaxis == 1 |
|
cont_values = linspace(lCont_initial(icont),lCont_initial(icont)-0.02,21); |
|
initial_idx = randi(length(cont_values)) |
|
lCont = cont_values(initial_idx) |
|
elseif iaxis == 2 |
|
cont_values = linspace(lumMod_initial(icont),lumMod_initial(icont)-.5,21); |
|
initial_idx = randi(length(cont_values)) |
|
lumMod = cont_values(initial_idx) |
|
end |
|
|
|
%%///////////////////////////////////////////////////////////////////////// |
|
%%/ SUBJECT INPUTS (RESPONSES) |
|
%%///////////////////////////////////////////////////////////////////////// |
|
|
|
DoneMatch = 0; |
|
|
|
while ~DoneMatch %look for key presses and put up stimulus |
|
[ keyIsDown, timeSecs, keyCode ] = KbCheck; |
|
if(CharAvail) % check for keypress, record if key=1 or 2 or 3 |
|
[char] = GetChar; |
|
switch char |
|
case '8' |
|
DoneMatch = 1; |
|
clc |
|
|
|
switch iaxis |
|
case 1 |
|
l_cont_match (irep, icont) = lCont |
|
case 2 |
|
lumMod_match (irep, icont) = lumMod |
|
lum_cont_match (irep, icont) = (lumMod) / maxLum |
|
end |
|
|
|
case '6' |
|
|
|
switch iaxis |
|
case 1 |
|
lCont = lCont + stepSize_l |
|
case 2 |
|
lumMod = lumMod + stepSize_lum |
|
end |
|
|
|
case '4' |
|
|
|
switch iaxis |
|
case 1 |
|
lCont = lCont - stepSize_l |
|
if lt(lCont,0) |
|
lCont=0 |
|
end |
|
case 2 |
|
lumMod = lumMod - stepSize_lum |
|
if lt(lumMod,0) |
|
lumMod=0 |
|
end |
|
end |
|
|
|
case '9' |
|
|
|
switch iaxis |
|
case 1 |
|
lCont = lCont + stepSize_l/5; |
|
case 2 |
|
lumMod = lumMod + stepSize_lum/10; |
|
end |
|
|
|
case '7' |
|
|
|
switch iaxis |
|
case 1 |
|
lCont = lCont - stepSize_l/5; |
|
if lt(lCont,0) |
|
lCont=0 |
|
end |
|
case 2 |
|
lumMod = lumMod - stepSize_lum/10; |
|
if lt(lumMod,0) |
|
lumMod=0 |
|
end |
|
end |
|
|
|
end |
|
FlushEvents('keyDown'); |
|
end |
|
|
|
%%///////////////////////////////////////////////////////////////////////// |
|
%%/ SET STIMULUS |
|
%%///////////////////////////////////////////////////////////////////////// |
|
%create colors depending on contrast |
|
switch iaxis |
|
case 1 |
|
l = [Bckg_Chro(iChro,1)+(Bckg_Chro(iChro,1)*lCont) Bckg_Chro(iChro,2) maxLum |
|
Bckg_Chro(iChro,1)-(Bckg_Chro(iChro,1)*lCont) Bckg_Chro(iChro,2) maxLum]; %+l, -l |
|
|
|
colLut = l; |
|
|
|
case 2 |
|
lum = [Bckg_Chro(iChro,1) Bckg_Chro(iChro,2) maxLum-lumMod |
|
Bckg_Chro(iChro,1) Bckg_Chro(iChro,2) maxLum+lumMod]; |
|
|
|
colLut = lum; |
|
end |
|
|
|
s = [Bckg_Chro(iChro,1) Bckg_Chro(iChro,2)+(Bckg_Chro(iChro,2)*sCont(icont)) maxLum |
|
Bckg_Chro(iChro,1) Bckg_Chro(iChro,2)-(Bckg_Chro(iChro,2)*sCont(icont)) maxLum];%+s, -s |
|
|
|
colLut_R = s; |
|
|
|
|
|
|
|
%LMS values of each color, ls to LMS |
|
for iLMS = 1:2 |
|
cLMS(iLMS,1) = colLut(iLMS,1)*colLut(iLMS, 3); |
|
cLMS(iLMS,2) = (1-colLut(iLMS,1))*colLut(iLMS, 3); |
|
cLMS(iLMS,3) = colLut(iLMS,2)*colLut(iLMS, 3); |
|
|
|
cLMS_R(iLMS,1) = colLut_R(iLMS,1)*colLut_R(iLMS, 3); |
|
cLMS_R(iLMS,2) = (1-colLut_R(iLMS,1))*colLut_R(iLMS, 3); |
|
cLMS_R(iLMS,3) = colLut_R(iLMS,2)*colLut_R(iLMS, 3); |
|
|
|
|
|
|
|
end |
|
|
|
%XYZ values for each |
|
for iXYZ = 1:length(cLMS(:,1)) |
|
cXYZ(iXYZ,:) = LMS_to_XYZ(cLMS(iXYZ,:)); |
|
|
|
cXYZ_R(iXYZ,:) = LMS_to_XYZ(cLMS_R(iXYZ,:)); |
|
end |
|
|
|
%use lut to find corrected monitor RGB values for each rgb color |
|
|
|
|
|
for iRGB = 1:length(cXYZ(:,1)) |
|
cRGB(iRGB,:) = XYZ_to_RGB(cXYZ(iRGB,:), maxPhosXYZ); |
|
cRGB(iRGB,1) = pix(dsearchn(redProp(:), cRGB(iRGB,1)))*hfpRG; |
|
cRGB(iRGB,2) = pix(dsearchn(grnProp(:), cRGB(iRGB,2))); |
|
cRGB(iRGB,3) = pix(dsearchn(blueProp(:), cRGB(iRGB,3)))*hfpBG; |
|
|
|
cRGB_R(iRGB,:) = XYZ_to_RGB(cXYZ_R(iRGB,:), maxPhosXYZ); |
|
cRGB_R(iRGB,1) = pix(dsearchn(redProp(:), cRGB_R(iRGB,1)))*hfpRG; |
|
cRGB_R(iRGB,2) = pix(dsearchn(grnProp(:), cRGB_R(iRGB,2))); |
|
cRGB_R(iRGB,3) = pix(dsearchn(blueProp(:), cRGB_R(iRGB,3)))*hfpBG; |
|
end |
|
|
|
|
|
Left = zeros(nFrames,3); |
|
Right = zeros(nFrames,3); |
|
for iRamp = 1:3 %for 3 phosophors |
|
Left(:,iRamp) = sinspaceOneCycle(wRGB(1,iRamp), cRGB(1,iRamp), nFrames); |
|
Right(:,iRamp) = sinspaceOneCycle(wRGB(1,iRamp), cRGB_R(1,iRamp), nFrames); |
|
end |
|
|
|
|
|
%%///////////////////////////////////////////////////////////////////////// |
|
%%/ DISPLAY STIMULUS |
|
%%///////////////////////////////////////////////////////////////////////// |
|
|
|
startT=GetSecs(); |
|
elapsedT=0; |
|
for iFrames = 1:nFrames |
|
|
|
|
|
Screen('FrameOval', window, 0 ,frameCircleLeft, frameWidth, frameWidth); |
|
Screen('FrameOval', window, 0 ,frameCircleRight, frameWidth, frameWidth); |
|
Screen('DrawLine', window, 0, lftXCircleCenter+circlePix/2+frameSize, center(2),... |
|
lftXCircleCenter+circlePix/2+frameSize-20, center(2), frameWidth); |
|
Screen('DrawLine', window, 0, lftXCircleCenter, center(2)+circlePix/2+frameSize,... |
|
lftXCircleCenter, center(2)+circlePix/2+frameSize-20, frameWidth); |
|
Screen('DrawLine', window, 0, rhtXCircleCenter-circlePix/2-frameSize, center(2),... |
|
rhtXCircleCenter-circlePix/2-frameSize+20, center(2), frameWidth); |
|
Screen('DrawLine', window, 0, rhtXCircleCenter, center(2)-circlePix/2-frameSize,... |
|
rhtXCircleCenter, center(2)-circlePix/2-frameSize+20, frameWidth); |
|
|
|
switch order |
|
case 0 |
|
%LEFT SEMICIRCLE |
|
Screen('FillArc', window, Left(iFrames,:), tstCircleRight, 180, 180); |
|
%Screen('FillArc', window, Left(iFrames,:), tstCircleRight, 180, 180); |
|
%Screen('FillArc', window, Right(iFrames,:), tstCircleLeft, 0, 180); |
|
Screen('FillArc', window, Right(iFrames,:), tstCircleLeft, 0, 180); |
|
vbl = Screen('Flip', window, vbl + (waitframes - 0.5) * ifi); |
|
|
|
case 1 |
|
%LEFT SEMICIRCLE |
|
Screen('FillArc', window, Right(iFrames,:), tstCircleRight, 180, 180); |
|
%Screen('FillArc', window, Left(iFrames,:), tstCircleRight, 180, 180); |
|
%Screen('FillArc', window, Right(iFrames,:), tstCircleLeft, 0, 180); |
|
Screen('FillArc', window, Left(iFrames,:), tstCircleLeft, 0, 180); |
|
|
|
%Screen('FillArc', window, Right(iFrames,:), tstcircle, 180, 180); |
|
%Screen('FillArc', window, Left(iFrames,:), tstcircle, 0, 180); |
|
vbl = Screen('Flip', window, vbl + (waitframes - 0.5) * ifi); |
|
|
|
end |
|
|
|
end |
|
|
|
end %while done |
|
|
|
|
|
|
|
count = count+1; |
|
elapsedT=GetSecs()-startT; |
|
FreqCheck = 1/elapsedT; |
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
|
% CHECK STOP BUTTON PUSHING? % |
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
|
|
|
yesno=evalin('base','Stop_Press') |
|
|
|
|
|
if yesno==1 |
|
return |
|
end |
|
|
|
% - - - - - - - - - - - - - - - - - - - - - - - - - - |
|
|
|
end % irep |
|
end %icont |
|
end % iaxis |
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
|
% FINAL VARIABLES % |
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
|
|
|
lCont_avg = median(l_cont_match,1); lCont_sd = std(l_cont_match,1); |
|
lumCont_avg = median(lum_cont_match,1); lumCont_sd = std(lum_cont_match,1); |
|
lumMod_avg = median(lumMod_match); |
|
Avg_MatchCont = [lCont_avg ; |
|
lumCont_avg]; |
|
|
|
|
|
TodayDate = datevec(date); |
|
for ii=1:nRep |
|
CoMatch_Date(ii,1:3) = TodayDate(1:3) ; |
|
end |
|
|
|
|
|
Dated_l_cont_match = [CoMatch_Date repelem(Bckg_Chro(iChro,:),nRep,1) l_cont_match]; |
|
Dated_lum_cont_match = [CoMatch_Date repelem(Bckg_Chro(iChro,:),nRep,1) lum_cont_match]; |
|
Dated_lumMod_match = [CoMatch_Date repelem(Bckg_Chro(iChro,:),nRep,1) lumMod_match]; |
|
|
|
|
|
if ~isempty(l_cont_match) |
|
Prev_l_cont_match = [Prev_l_cont_match ; |
|
Dated_l_cont_match]; |
|
end |
|
|
|
if ~isempty(lum_cont_match) |
|
Prev_lum_cont_match = [Prev_lum_cont_match ; |
|
Dated_lum_cont_match]; |
|
|
|
Prev_lumMod_match = [Prev_lumMod_match ; |
|
Dated_lumMod_match]; |
|
end |
|
|
|
|
|
if gt(size(Prev_l_cont_match,1),4)% Final values of contrast for the afterimage program |
|
idx_l = find(and(Prev_l_cont_match(:,4) == Bckg_Chro(iChro,1), Prev_l_cont_match(:,5) == Bckg_Chro(iChro,2) )) |
|
idx_lum = find(and(Prev_lum_cont_match(:,4) == Bckg_Chro(iChro,1), Prev_lum_cont_match(:,5) == Bckg_Chro(iChro,2) )) |
|
idx_lumMod = find(and(Prev_lumMod_match(:,4) == Bckg_Chro(iChro,1), Prev_lumMod_match(:,5) == Bckg_Chro(iChro,2) )) |
|
|
|
|
|
Final_lCont_avg(iChro,:) = [Bckg_Chro(iChro,:) median(Prev_l_cont_match(idx_l,end-3:end))]; |
|
Final_lumCont_avg(iChro,:) = [Bckg_Chro(iChro,:) median(Prev_lum_cont_match(idx_lum,end-3:end))]; |
|
Final_lumMod_avg(iChro,:) = [Bckg_Chro(iChro,:) median(Prev_lumMod_match(idx_lumMod,end-3:end))]; |
|
else |
|
Msg = 'MORE MEASUREMENTS ARE NEEDEED' |
|
Final_lCont_avg = []; |
|
Final_lumCont_avg = []; |
|
Final_lumMod_avg = []; |
|
|
|
end |
|
Final_sCont_ref = sCont; |
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
|
% PLOT AND SAVE % |
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
|
|
|
f(iChro) = figure |
|
|
|
if ~isempty(l_cont_match) |
|
errorbar(sCont,lCont_avg,lCont_sd,'r*--','MarkerSize',15); hold on |
|
end |
|
|
|
if ~isempty(lum_cont_match) |
|
errorbar(sCont,lumCont_avg,lumCont_sd,'k*--','MarkerSize',15); |
|
end |
|
|
|
switch iChro |
|
case 1 |
|
set(f(iChro), 'Position', [1100 770 500 500]); |
|
title('North (blueish)') |
|
case 2 |
|
set(f(iChro), 'Position', [1100 170 500 500]); |
|
title('South (yellowish)') |
|
case 3 |
|
set(f(iChro), 'Position', [400 470 500 500]); |
|
title('West (greenish)') |
|
case 4 |
|
set(f(iChro), 'Position', [1700 470 500 500]); |
|
title('East (redish)') |
|
end |
|
|
|
|
|
end% iChro |
|
|
|
Screen('CloseAll') |
|
|
|
%aa = cd('/Users/clemente/Desktop/AfterImage Programs/A Outputs'); |
|
save(saveFile,'Final_lCont_avg','Final_lumCont_avg','Final_lumMod_avg','Final_sCont_ref',... |
|
'Prev_l_cont_match','Prev_lum_cont_match','Prev_lumMod_match') |
|
|
|
sca |
|
|
|
figure(1);figure(2);figure(3);figure(4); %bring figures to front |
|
|
|
catch ME |
|
disp(ME); |
|
warndlg('The program failed to run. Try again.') |
|
return |
|
|
|
end |
|
|
|
|
|
end |