-
Notifications
You must be signed in to change notification settings - Fork 1
/
noiseTasks.m
187 lines (177 loc) · 5.14 KB
/
noiseTasks.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
% noiseTasks.m
% April 4, 2018
% Denis Pelli for project in collaboration with Martin Barlow and Horace
% Barlow and Michelle Qiu.
%% GET READY
clear o oo
skipDataCollection=false; % Enable skipDataCollection to check plotting before we have data.
o.questPlusEnable=false;
if ~exist('struct2table','file')
error('This MATLAB %s is too old. We need MATLAB 2013b or better to use the function "struct2table".',version('-release'));
end
if ~exist('qpInitialize','file')
addpath('~/Dropbox/mQuestPlus');
addpath('~/Dropbox/mQuestPlus/questplus');
end
if ~exist('qpInitialize','file')
error('This script requires the QuestPlus package. Please get it from https://github.com/BrainardLab/mQUESTPlus.')
end
addpath(fullfile(fileparts(mfilename('fullpath')),'lib')); % Folder in same directory as this M file.
cal=OurScreenCalibrations(0);
o.localHostName=cal.localHostName;
% o.useFractionOfScreenToDebug=0.4; % 0: normal, 0.5: small for debugging.
% o.measureContrast=true;
% o.printImageStatistics=true;
% o.assessTargetLuminance=true;
o.observer='ideal';
o.observer='junk';
o.experimenter='junk';
%% SPECIFY BASIC CONDITION
o.experiment='noiseTasks';
o.nearPointXYInUnitSquare=[0.5 0.5];
o.eccentricityXYDeg=[0,0];
o.targetHeightDeg=2;
o.noiseCheckDeg=o.targetHeightDeg/20;
o.targetDurationSec=0.2;
o.eyes='both';
o.contrast=-0.1;
o.viewingDistanceCm=40;
o.isLuminanceRangeSymmetric=true;
o.alphabetPlacement='right'; % 'top' or 'right';
o.fixationThicknessDeg=0.09;
o.fixationBlankingRadiusReEccentricity=0; % No blanking.
o.fixationBlankingRadiusReTargetHeight=0;
o.targetMarkDeg=2;
o.fixationMarkDeg=3;
if true
% Target letter
o.targetKind='letter';
o.targetFont='Sloan';
o.alphabet='DHKNORSVZ';
o.contrast=-1; % negative contrast.
else
% Target gabor
o.targetKind='gabor';
o.targetGaborOrientationsDeg=[0 45 90 135];
o.targetGaborNames='1234';
o.alphabet=o.targetGaborNames;
o.contrast=1; % positive contrast.
end
if false
% Use QuestPlus to measure steepness.
o.questPlusEnable=true;
o.questPlusSteepnesses=1:0.1:5;
o.questPlusGuessingRates=1/o.alternatives;
o.questPlusLapseRates=0:0.01:0.05;
o.questPlusLogIntensities=-2.5:0.05:0.5;
o.questPlusPrint=true;
o.questPlusPlot=true;
end
o.thresholdParameter='contrast';
o.trialsDesired=40;
%% PUT THE EXPERIMENT'S CONDITIONS IN STRUCT oo
o.targetHeightDeg=11;
o.noiseRadiusDeg=o.targetHeightDeg/2;
o.noiseCheckDeg=o.targetHeightDeg/20;
o.noiseSD=0.2;
o.targetDurationSec=0.2;
o.fixationMarkDrawnOnStimulus=true;
o.isTargetLocationMarked=true; % Is there a mark designating target position?
o.targetMarkDeg=0.1;
o.contrast=-1;
oo={};
if true
o.conditionName='Noise letter';
o.task='identify';
o.targetModulates='noise';
o.targetKind='letter';
o.eccentricityXYDeg=[5.6 5.6];
oo{end+1}=o;
o.eccentricityXYDeg=[0 0];
end
if true
o.conditionName='Luminance letter';
o.task='identify';
o.targetModulates='luminance';
oo{end+1}=o;
end
if true
o.conditionName='Entropy letter 2';
o.task='identify';
o.targetModulates='entropy';
o.backgroundEntropyLevels=2;
o.targetHeightDeg=11;
o.noiseCheckDeg=o.targetHeightDeg/20;
o.targetDurationSec=inf;
o.noiseSD=0.2;
oo{end+1}=o;
% o.noiseSD=0.05;
oo{end+1}=o;
end
if true
o.conditionName='Entropy letter 3';
o.task='identify';
o.targetModulates='entropy';
o.backgroundEntropyLevels=3;
o.targetHeightDeg=11;
o.noiseCheckDeg=o.targetHeightDeg/20;
o.targetDurationSec=inf;
o.noiseSD=0.2;
oo{end+1}=o;
% o.noiseSD=0.05;
oo{end+1}=o;
end
if true
o.conditionName='4afc noise';
o.task='4afc';
o.targetModulates='noise';
% o.targetHeightDeg=8;
% o.noiseCheckDeg=o.targetHeightDeg/100;
oo{end+1}=o;
end
if false
o.conditionName='4afc luminance';
o.task='4afc';
o.targetModulates='luminance';
oo{end+1}=o;
end
if false
o.conditionName='4afc entropy';
o.task='4afc';
o.targetModulates='entropy';
o.backgroundEntropyLevels=3;
oo{end+1}=o;
end
%% POLISH THE LIST OF CONDITIONS
for oi=1:length(oo)
o=oo{oi};
o.condition=oi; % Number the conditions
o.alternatives=length(o.alphabet);
if all(o.eccentricityXYDeg==0)
o.isTargetLocationMarked=false;
else
o.isTargetLocationMarked=true;
end
oo{oi}=o;
end
%% PRINT THE CONDITIONS (ONE PER ROW) AS TABLE TT
% All these vars must be defined in every condition.
vars={'condition' 'conditionName' 'trialsDesired' 'noiseSD' 'targetHeightDeg' 'task' 'targetModulates' 'contrast'};
tt=table;
for i=1:length(oo)
t=struct2table(oo{i},'AsArray',true);
tt(i,:)=t(1,vars);
end
disp(tt) % Print the oo list of conditions.
%% RUN THE CONDITIONS
oo=RunExperiment(oo);
%% PRINT SUMMARY OF RESULTS AS TABLE TT
% Include whatever you're intersted in. We skip rows missing any specified variable.
vars={'condition' 'conditionName' 'observer' 'trials' 'p' 'trialsSkipped' ...
'task' 'targetModulates' 'noiseSD' 'N' 'targetHeightDeg' ...
'contrast' 'r' 'approxRequiredNumber' 'backgroundEntropyLevels' };
tt=Experiment2Table(oo,vars);
disp(tt) % Print the list of conditions, with results.
if isempty(tt)
return
end