pb_vReadExp.m 8.16 KB
Newer Older
1
function [block,cfg] = pb_vReadExp(cfg)
2
% PB_VREADEXP
Jesse Heckman's avatar
Jesse Heckman committed
3
%
4
% PB_VREADEXP(cfg) reads experimental data from expfile and loads it in 
5
% 'block' and 'cfg'.
Jesse Heckman's avatar
Jesse Heckman committed
6
%
7
% See also PB_VPRIME, PB_VPRIMEGUI, PB_VRUNEXP, PB_GETBLOCK
Jesse Heckman's avatar
Jesse Heckman committed
8
9
10
11
12

% PBToolbox (2018): JJH: j.heckman@donders.ru.nl

   %% INITIALIZE
   
13
   expfile     = cfg.expfname;
Jesse Heckman's avatar
Jesse Heckman committed
14
   if ~pb_fexist(expfile); return; end
15
   fid         = fopen(expfile,'r');
Jesse Heckman's avatar
Jesse Heckman committed
16
   
Jesse Heckman's avatar
Jesse Heckman committed
17
   %% HEADER
Jesse Heckman's avatar
Jesse Heckman committed
18
   
Jesse Heckman's avatar
Jesse Heckman committed
19
20
21
22
23
24
   cfg.comment = checkcomment(fid);
   cfg         = hread(fid,cfg);
   n           = cfg.Blocks;
   
   %% EXP
   
25
26
27
   block                	= struct([]);
   block(1).signal        	= [];
   block(1).trial        	= [];
Jesse Heckman's avatar
Jesse Heckman committed
28
29
30

   bn = 0;
   while ~feof(fid)
31
32
33
      
      tline          = fgetl(fid);
      firstCell      = sscanf(tline,'%s',1);
Jesse Heckman's avatar
Jesse Heckman committed
34
      nchar				= length(firstCell);
35
      
Jesse Heckman's avatar
Jesse Heckman committed
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
      if strcmp(firstCell,'%'); firstCell = sscanf(tline,'%s',2); firstCell = firstCell(2:end-1); end

      switch upper(firstCell)
         case 'BLOCK'
            % Updates counts for block
            bn = bn+1; tn = 0; sn = 0;
            fgetl(fid); 
         
         case 'TRIAL'
            % Updates counts for trial
            tn = tn+1; sn = 0;
            
         case 'HOR'
            % Writes horizontal vestibular signal for block
            block(bn).signal.hor = readVest(tline); 
            
         case 'VER'
            % Writes vertical vestibular signal for block
            block(bn).signal.ver = readVest(tline); 
            
         case {'SND','SND1','SND2'}
            % Updates count and writes stimulus
            sn    = sn+1;
Jesse Heckman's avatar
Jesse Heckman committed
59
            par   = sscanf(tline(nchar+1:end),'%d%d%d%f%d%d',[7,1]);
Jesse Heckman's avatar
Jesse Heckman committed
60
61
62
63
            
            block(bn).trial(tn).stim(sn).modality		= 'sound';
            block(bn).trial(tn).stim(sn).X            = par(1);
            block(bn).trial(tn).stim(sn).Y            = par(2);
Jesse Heckman's avatar
Jesse Heckman committed
64
            block(bn).trial(tn).stim(sn).parameters	= par(3);
Jesse Heckman's avatar
Jesse Heckman committed
65
66
67
            block(bn).trial(tn).stim(sn).intensity    = par(4);
            block(bn).trial(tn).stim(sn).onevent		= par(5);
            block(bn).trial(tn).stim(sn).ondelay		= par(6);
68
            block(bn).trial(tn).stim(sn).offdelay		= par(5)+par(7);
Jesse Heckman's avatar
Jesse Heckman committed
69
            block(bn).trial(tn).stim(sn).duration		= par(7);
Jesse Heckman's avatar
Jesse Heckman committed
70
71
72
73
74
75
76
77
78
            
         case {'LED','LED1','LED2'}
            % Updates count and writes stimulus
            sn    = sn+1;
            par   = sscanf(tline(nchar+1:end),'%d%d%d%d%d%d%d',[7,1]);
				
            block(bn).trial(tn).stim(sn).modality		= 'LED';
				block(bn).trial(tn).stim(sn).X            = par(1);
				block(bn).trial(tn).stim(sn).Y            = par(2);
Jesse Heckman's avatar
Jesse Heckman committed
79
				block(bn).trial(tn).stim(sn).intensity    = par(3);  % vestibular 0-100
Jesse Heckman's avatar
Jesse Heckman committed
80
81
82
83
84

				block(bn).trial(tn).stim(sn).onevent		= par(4);
				block(bn).trial(tn).stim(sn).ondelay		= par(5);
				block(bn).trial(tn).stim(sn).offevent		= par(6);
				block(bn).trial(tn).stim(sn).offdelay		= par(7);
85
            block(bn).trial(tn).stim(sn).duration		= par(7)-par(5);
86
 
Jesse Heckman's avatar
Jesse Heckman committed
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
         case 'TRG0'
            % Updates count and writes stimulus
            sn    = sn+1;
            par	= sscanf(tline(nchar+1:end),'%d%d%d%d%d',[5,1]);
            
            block(bn).trial(tn).stim(sn).modality		= 'trigger';
            if par(1) == 1
               block(bn).trial(tn).stim(sn).detect		= 'rise';
            elseif par==2
               block(bn).trial(tn).stim(sn).detect		= 'fall';
            end
            block(bn).trial(tn).stim(sn).channel		= par(2);
            block(bn).trial(tn).stim(sn).onevent		= par(3);
            block(bn).trial(tn).stim(sn).ondelay		= par(4);
            block(bn).trial(tn).stim(sn).event        = par(5);
102
            
Jesse Heckman's avatar
Jesse Heckman committed
103
104
105
106
107
108
109
110
111
         case 'ACQ'
            % Updates count and writes stimulus
            sn    = sn+1;
            par	= sscanf(tline(nchar+1:end),'%d%d',[2,1]); % could also be 3
            
            block(bn).trial(tn).stim(sn).modality		= 'data acquisition';
            block(bn).trial(tn).stim(sn).onevent		= par(1);
            block(bn).trial(tn).stim(sn).ondelay		= par(2);
      end
112
113
   end
   cfg		= pb_vLookup(cfg);
114

115
   for iBlck = 1:cfg.Blocks
116
      
117
118
      ntrials = length(block(iBlck).trial);
      for iTrl = 1:ntrials % for every trial
119
120
         
         s = block(iBlck).trial(iTrl).stim;
121
         block(iBlck).trial(iTrl).nstim = numel(s); % number of stimuli per trial
122
123
124
125
126
127
         for iStm	= 1:block(iBlck).trial(iTrl).nstim % for every stimulus in a trial
            
            X			= block(iBlck).trial(iTrl).stim(iStm).X;
            Y			= block(iBlck).trial(iTrl).stim(iStm).Y;
            mod			= block(iBlck).trial(iTrl).stim(iStm).modality;
            
128
129
            if ~isempty(X) % for every stimulus that has an X and Y parameter, determine azimuth and elevation
               if cfg.Lab==1 % Hoop lab
130
                  
131
132
133
134
135
                  if strcmpi(mod,'sky')
                     [Az,El] = hoopsky2azel(X,Y);
                  else
                     [Az,El]	= hoopXY2azel(X,Y);
                  end
136
                  
137
               elseif ismember(cfg.Lab,[2 3]) % Sphere lab
138
                  
139
140
141
                  channel = cfg.interpolant(X,Y);
                  Az		= cfg.lookup(channel+1,5);
                  El		= cfg.lookup(channel+1,6);
142
                  
143
               elseif ismember(cfg.Lab,4) % SphereMinor lab
144
                  
145
146
147
                  channel = cfg.interpolant(X,Y);
                  Az		= cfg.lookup(channel+1,4);
                  El		= cfg.lookup(channel+1,5);
148
                  
149
               elseif ismember(cfg.Lab,5) % vPrime lab
150
                  
151
152
153
                  channel = cfg.interpolant(X,Y);
                  Az		= cfg.lookup(channel+1,4);
                  El		= cfg.lookup(channel+1,5);
154
                  
155
               end
156
157
               block(iBlck).trial(iTrl).stim(iStm).azimuth        = Az;
               block(iBlck).trial(iTrl).stim(iStm).elevation      = El;
158
159
160
            end
         end
      end
Jesse Heckman's avatar
Jesse Heckman committed
161
   end
162
	fclose(fid);
Jesse Heckman's avatar
Jesse Heckman committed
163
164
end

Jesse Heckman's avatar
Jesse Heckman committed
165
function comment = checkcomment(fid)
166
167
   % reads comments from the expfile

Jesse Heckman's avatar
Jesse Heckman committed
168
169
170
   isComment	= true;
   cnt			= 0; % counter
   comment		= cell(1);
171
   
Jesse Heckman's avatar
Jesse Heckman committed
172
173
174
175
176
177
178
179
180
   while isComment % do this for every line that starts with '%'
      position	= ftell(fid); % find the position in the file
      str			= fscanf(fid,'%s',1); % read the string (moving the position in the file)
      commentline = fgetl(fid); % get the entire line (again repositioning)
      isComment	= strncmp(str,'%',1); % and check whether the first string of the line actually indicated a comment
      if ~isempty(commentline) && isComment
         cnt				= cnt+1;
         comment(cnt)	= {commentline};
      end
Jesse Heckman's avatar
Jesse Heckman committed
181
   end
Jesse Heckman's avatar
Jesse Heckman committed
182
183
184
185
   fseek(fid,position,'bof');
end

function cfg = hread(fid,cfg)
186
187
   % reads the header from the expfile

Jesse Heckman's avatar
Jesse Heckman committed
188
189
190
   cnt = 0;
   isBody = false;
   header = cell(1);
Jesse Heckman's avatar
Jesse Heckman committed
191
   
Jesse Heckman's avatar
Jesse Heckman committed
192
   while ~isBody
193
      
Jesse Heckman's avatar
Jesse Heckman committed
194
195
      position	= ftell(fid);
      str      = fscanf(fid,'%s',1);
196
197
      isBody   = strcmp(str,'~~~');
      
Jesse Heckman's avatar
Jesse Heckman committed
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
      if ~isBody
         fseek(fid,position,'bof');
         cnt			= cnt+1;
         header(cnt)	= {fscanf(fid,'%s',1)};
         switch lower(header{cnt})
            case 'iti' % Inter-trial interval
               cfg.(header{cnt})	= fscanf(fid,'%d %d',[2 1]); % 2 integers: minimum and maximum possible inter trial interval
            case 'motor' % Motor
               cfg.(header{cnt})	= fscanf(fid,'%s',1); % String: yes or no
            otherwise
               cfg.(header{cnt})	= fscanf(fid,'%d',1); % Integer
         end
         checkcomment(fid);
      end  
   end
Jesse Heckman's avatar
Jesse Heckman committed
213
214
end

Jesse Heckman's avatar
Jesse Heckman committed
215
function signal = readVest(line)
216
217
   % reads VS signal from the expfile
   
218
   types = {'none','sine','noise','turn','vor'};
Jesse Heckman's avatar
Jesse Heckman committed
219
   n = str2num(erase(sscanf(line,'%s',2),sscanf(line,'%s',1)));
Jesse Heckman's avatar
Jesse Heckman committed
220
221
   type  = types{n};
   signal.type = type;
Jesse Heckman's avatar
Jesse Heckman committed
222
223
224
225

   signal.amplitude  = str2double(erase(sscanf(line,'%s',3),sscanf(line,'%s',2)));
   signal.duration   = str2double(erase(sscanf(line,'%s',4),sscanf(line,'%s',3)));
   signal.frequency  = str2double(erase(sscanf(line,'%s',5),sscanf(line,'%s',4)));
Jesse Heckman's avatar
Jesse Heckman committed
226
end
Jesse Heckman's avatar
Jesse Heckman committed
227

Jesse Heckman's avatar
Jesse Heckman committed
228
229
230
231
232
233
234
% % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % 
%                                                           %
%       Part of Programmeer Beer Toolbox (PBToolbox)        %
%       Written by: Jesse J. Heckman (2018)                 %
%                                                           %
% % % % % % % % % % % % % % % % % % % % % % % % % % % % % % %