TEAP (Toolbox for Emotion Analysis using Physiological Signals) doc
eeg_checkchanlocs.m
Go to the documentation of this file.
1 % eeg_checkchanlocs() - Check the consistency of the channel locations structure
2 % of an EEGLAB dataset.
3 %
4 % Usage:
5 % >> EEG = eeg_checkchanlocs( EEG, 'key1', value1, 'key2', value2, ... );
6 % >> [chanlocs chaninfo] = eeg_checkchanlocs( chanlocs, chaninfo, 'key1', value1, 'key2', value2, ... );
7 %
8 % Inputs:
9 % EEG - EEG dataset
10 % chanlocs - EEG.chanlocs structure
11 % chaninfo - EEG.chaninfo structure
12 %
13 % Outputs:
14 % EEG - new EEGLAB dataset with updated channel location structures
15 % EEG.chanlocs, EEG.urchanlocs, EEG.chaninfo
16 % chanlocs - updated channel location structure
17 % chaninfo - updated chaninfo structure
18 %
19 % Author: Arnaud Delorme, SCCN/INC/UCSD, March 2, 2011
20 
21 % Copyright (C) SCCN/INC/UCSD, March 2, 2011, arno@salk.edu
22 %
23 % This program is free software; you can redistribute it and/or modify
24 % it under the terms of the GNU General Public License as published by
25 % the Free Software Foundation; either version 2 of the License, or
26 % (at your option) any later version.
27 %
28 % This program is distributed in the hope that it will be useful,
29 % but WITHOUT ANY WARRANTY; without even the implied warranty of
30 % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
31 % GNU General Public License for more details.
32 %
33 % You should have received a copy of the GNU General Public License
34 % along with this program; if not, write to the Free Software
35 % Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
36 
37 % Hey Arno -- this is a quick fix to make an analysis work for Makoto
38 % I think the old version had a bug...
39 
40 function [chans, chaninfo, chanedit]= eeg_checkchanlocs(chans, chaninfo);
41 
42 if nargin < 1
43  help eeg_checkchanlocs;
44  return;
45 end;
46 
47 if nargin < 2
48  chaninfo = [];
49 end;
50 
51 processingEEGstruct = 0;
52 if isfield(chans, 'data')
53  processingEEGstruct = 1;
54  tmpEEG = chans;
55  chans = tmpEEG.chanlocs;
56  chaninfo = tmpEEG.chaninfo;
57 end;
58 
59 if ~isfield(chans, 'datachan')
60  [chanedit,dummy,complicated] = insertchans(chans, chaninfo);
61 else
62  chanedit = chans;
63  complicated = true;
64 end;
65 
66 nosevals = { '+X' '-X' '+Y' '-Y' };
67 if ~isfield(chaninfo, 'plotrad'), chaninfo.plotrad = []; end;
68 if ~isfield(chaninfo, 'shrink'), chaninfo.shrink = []; end;
69 if ~isfield(chaninfo, 'nosedir'), chaninfo.nosedir = nosevals{1}; end;
70 
71 % handles deprecated fields
72 % -------------------------
73 plotrad = [];
74 if isfield(chanedit, 'plotrad'),
75  plotrad = chanedit(1).plotrad;
76  chanedit = rmfield(chanedit, 'plotrad');
77  if isstr(plotrad) & ~isempty(str2num(plotrad)), plotrad = str2num(plotrad); end;
78  chaninfo.plotrad = plotrad;
79 end;
80 if isfield(chanedit, 'shrink') && ~isempty(chanedit(1).shrink)
81  shrinkorskirt = 1;
82  if ~isstr(chanedit(1).shrink)
83  plotrad = 0.5/(1-chanedit(1).shrink); % convert old values
84  end;
85  chanedit = rmfield(chanedit, 'shrink');
86  chaninfo.plotrad = plotrad;
87 end;
88 
89 % set non-existent fields to []
90 % -----------------------------
91 fields = { 'labels' 'theta' 'radius' 'X' 'Y' 'Z' 'sph_theta' 'sph_phi' 'sph_radius' 'type' 'ref' 'urchan' };
92 fieldtype = { 'str' 'num' 'num' 'num' 'num' 'num' 'num' 'num' 'num' 'str' 'str' 'num' };
93 check_newfields = true; %length(fieldnames(chanedit)) < length(fields);
94 if ~isempty(chanedit)
95  for index = 1:length(fields)
96  if check_newfields && ~isfield(chanedit, fields{index})
97  % new field
98  % ---------
99  if strcmpi(fieldtype{index}, 'num')
100  chanedit = setfield(chanedit, {1}, fields{index}, []);
101  else
102  for indchan = 1:length(chanedit)
103  chanedit = setfield(chanedit, {indchan}, fields{index}, '');
104  end;
105  end;
106  else
107  % existing fields
108  % ---------------
109  allvals = {chanedit.(fields{index})};
110  if strcmpi(fieldtype{index}, 'num')
111  if ~all(cellfun('isclass',allvals,'double'))
112  numok = cellfun(@isnumeric, allvals);
113  if any(numok == 0)
114  for indConvert = find(numok == 0)
115  chanedit = setfield(chanedit, {indConvert}, fields{index}, []);
116  end;
117  end;
118  end
119  else
120  strok = cellfun('isclass', allvals,'char');
121  if strcmpi(fields{index}, 'labels'), prefix = 'E'; else prefix = ''; end;
122  if any(strok == 0)
123  for indConvert = find(strok == 0)
124  try
125  strval = [ prefix num2str(getfield(chanedit, {indConvert}, fields{index})) ];
126  chanedit = setfield(chanedit, {indConvert}, fields{index}, strval);
127  catch
128  chanedit = setfield(chanedit, {indConvert}, fields{index}, '');
129  end;
130  end;
131  end;
132  end;
133  end;
134  end;
135 end;
136 if ~isequal(fieldnames(chanedit)',fields)
137  try
138  chanedit = orderfields(chanedit, fields);
139  catch, end;
140 end
141 
142 % check if duplicate channel label
143 % --------------------------------
144 if isfield(chanedit, 'labels')
145  tmp = sort({chanedit.labels});
146  if any(strcmp(tmp(1:end-1),tmp(2:end)))
147  disp('Warning: some channels have the same label');
148  end
149 end;
150 
151 % remove fields
152 % -------------
153 if isfield(chanedit, 'sph_phi_besa' ), chanedit = rmfield(chanedit, 'sph_phi_besa'); end;
154 if isfield(chanedit, 'sph_theta_besa'), chanedit = rmfield(chanedit, 'sph_theta_besa'); end;
155 
156 % reconstruct the chans structure
157 % -------------------------------
158 if complicated
159  [chans chaninfo.nodatchans] = getnodatchan( chanedit );
160  if ~isfield(chaninfo, 'nodatchans'), chaninfo.nodatchans = []; end;
161  if isempty(chanedit)
162  for iField = 1:length(fields)
163  chanedit = setfield(chanedit, fields{iField}, []);
164  end;
165  end;
166 else
167  chans = rmfield(chanedit,'datachan');
168  chaninfo.nodatchans = [];
169 end
170 
171 if processingEEGstruct
172  tmpEEG.chanlocs = chans;
173  tmpEEG.chaninfo = chaninfo;
174  chans = tmpEEG;
175 end;
176 
177 % ---------------------------------------------
178 % separate data channels from non-data channels
179 % ---------------------------------------------
180 function [chans, fidsval] = getnodatchan(chans)
181 if isfield(chans,'datachan')
182  [chans(cellfun('isempty',{chans.datachan})).datachan] = deal(0);
183  fids = [chans.datachan] == 0;
184  fidsval = chans(fids);
185  chans = rmfield(chans(~fids),'datachan');
186 else
187  fids = [];
188 end;
189 
190 % ----------------------------------------
191 % fuse data channels and non-data channels
192 % ----------------------------------------
193 function [chans, chaninfo,complicated] = insertchans(chans, chaninfo, nchans)
194 if nargin < 3, nchans = length(chans); end;
195 [chans.datachan] = deal(1);
196 complicated = false; % whether we need complicated treatment of datachans & co further down the road.....
197 
198 if isfield(chans,'type')
199  mask = strcmpi({chans.type},'FID') | strcmpi({chans.type},'IGNORE');
200  if any(mask)
201  [chans(mask).datachan] = deal(0);
202  complicated = true;
203  end
204 end
205 if length(chans) > nchans & nchans ~= 0 % reference at the end of the structure
206  chans(end).datachan = 0;
207  complicated = true;
208 end;
209 if isfield(chaninfo, 'nodatchans')
210  if ~isempty(chaninfo.nodatchans) && isstruct(chaninfo.nodatchans)
211  chanlen = length(chans);
212  for index = 1:length(chaninfo.nodatchans)
213  fields = fieldnames( chaninfo.nodatchans );
214  ind = chanlen+index;
215  for f = 1:length( fields )
216  chans = setfield(chans, { ind }, fields{f}, getfield( chaninfo.nodatchans, { index }, fields{f}));
217  end;
218  chans(ind).datachan = 0;
219  complicated = true;
220  end;
221  chaninfo = rmfield(chaninfo, 'nodatchans');
222 
223  % put these channels first
224  % ------------------------
225  % tmp = chans(chanlen+1:end);
226  % chans(length(tmp)+1:end) = chans(1:end-length(tmp));
227  % chans(1:length(tmp)) = tmp;
228  end;
229 end;
eeg_checkchanlocs
function eeg_checkchanlocs(in chans, in chaninfo)
getnodatchan
function getnodatchan(in chans)
insertchans
function insertchans(in chans, in chaninfo, in nchans)