Load sensor position, sensor direction, weight of MEG (meg.mat) and EEG (eeg.mat). This function supports three formats of megfile; Standard MEG format, Minimum MEG format and fileinfo format. By default, this function load only active sensors kept in MEGinfo.ActiveChannel in case of Standard MEG format or fileinfo.channel_id in case of fileinfo format. [usage] 1. Load active sensors(Default) [pick, Qpick, CoilWeight, Vcenter, result, channel_info] = ... vb_load_sensor(megfile); 2. Load all sensors including inactive sensors. active_swt = false; [pick, Qpick, CoilWeight, Vcenter, result, channel_info] = ... vb_load_sensor(megfile, [], [], active_swt); [input] megfile : <required> <<file>> MEG-MAT file or EEG-MAT file ch_type : <optional> <<string>> channel type [''] : '' or 'MEG' : MEG channels of MEG : 'REF' : REFFERENCE channels of MEG : 'ALL' : MEG + REFFERENCE channels of MEG : 'MAG' : magnetometer channels : 'AXIAL' : axial channels : 'PLANAR' : planar channels : 'MAG_X' : Magnetometer OPM channel data toward X-axis (only QZFM device) : 'MAG_Y' : Magnetometer OPM channel data toward Y-axis (only QZFM device) : 'MAG_Z' : Magnetometer OPM channel data toward Z-axis (only QZFM device) : case-insensitive ch_name : <optional> <<cell array>> channel name list [{''}(empty)] : If ch_type is specified, this is ignored. active_swt : <optional> <<boolean>> switch to filter channel : if .ActiveChannel is valid [true] : if .ActiveChannel is invalid [false] : true) return only active channels : false) return all the channels method : <optional> method of calculation : ['AVE'] : average : 'TOP' : use top data : this is valid for 'INIT' mode [output] pick : n-th coil position (Right-hand SPM coordinate) [m] : [Ncoil x 3] Qpick : n-th coil direction (Right-hand SPM coordinate) : [Ncoil x 3] CoilWeight : n-th coil weight for m-th channel [Nchannel x Ncoil] : basis(channel,dipole) = CoilWeight * basis(coil,dipole) Vcenter : Center of spherical head model [m] [1 x 3] result : <<integer>> error infomation : In the case that meg_file is '.info.mat' file and method is : 'AVE', this will become error struct. : fields are as follows: : These are errors between base data of each file and average. : .error_pick [n_ch x 3 x n_file] : .error_Qpick [n_ch x 3 x n_file] (if they are) channel_info : <<struct>> channel information of loaded data. : .Active [Nchannel x 1] : .Name [Nchannel x 1] : .Type [Nchannel x 1] : .ID [Nchannel x 1] : return empty when the loaded data contains reference sensor. ('REF', 'ALL') [note] if megfile is SBI data file or EEG-MAT file, REFFERENCE channel is empty [Active channel/Active trial information] * Place load(megfile, 'MEGinfo'); % EEG case, MEGinfo -> EEGinfo MEGInfo.ActiveChannel : Active channel list (boolean array) [Nchannelx 1] .ActiveTrial : Active trial list (boolean array) [Nrepeat x 1] * Inactivate channel/trial load_spec.ActiveChannel = false; load_spec.ActiveTrial = false; [data] = vb_load_meg_data(meg_file, load_spec); % [Nchannel x Nsample x Ntrial] MEGinfo.ActiveChannel = ones(size(data, 1), 1); % All channel active MEGinfo.ActiveTrial = ones(size(data, 3), 1); % All trial active % Inactivate channel/trial MEGinfo.ActiveChannel(N) = 0; % Inactive data(N, :, :) MEGinfo.ActiveTrial(M) = 0; % Inactive data(:, :, M) then save it. vb_save(megfile, 'MEGinfo'); [see also] vb_megfile_get_sensor_position_by_name vb_megfile_get_sensor_position_by_type [history] 2006-11-01 (Sako) modified to be able to accept EEGinfo 2007-07-24 (Sako) added channel mode 2008-04-16 (Sako) added active_swt, result 2008-06-04 (Sako) changed default value of active_swt 2009-08-21 (????) supported 'INFO' as "Measurement" but 'mode' is ignored 2010-08-24 (Sako) added method argument 2011-06-02 (Sako) converted return values of vb_load_device to upper case 2011-07-26 (Sako) changed mode to ch_type, added ch_name as arguments 2017-03-06 (rhayashi) supported ch_type, ch_name for fileinfo format. 2017-04-15 (rhayashi) bugfix:ActiveChannel field work correctly. 2018-08-22 (Takeda) removed warning message about Vcenter and supported NEUROMAG 2022-06-03 (k_suzuki) supported QZFM 2022-06-24 (k_suzuki) fixed bug when load Info file of QZFM device Copyright (C) 2011, ATR All Rights Reserved. License : New BSD License(see VBMEG_LICENSE.txt)
0001 function [pick, Qpick, CoilWeight, Vcenter, result, channel_info] = ... 0002 vb_load_sensor(megfile, ch_type, ch_name, active_swt, method) 0003 % Load sensor position, sensor direction, weight of MEG (meg.mat) and EEG (eeg.mat). 0004 % 0005 % This function supports three formats of megfile; Standard MEG format, Minimum MEG format and fileinfo format. 0006 % By default, this function load only active sensors kept in MEGinfo.ActiveChannel 0007 % in case of Standard MEG format or fileinfo.channel_id in case of fileinfo format. 0008 % 0009 % [usage] 0010 % 1. Load active sensors(Default) 0011 % [pick, Qpick, CoilWeight, Vcenter, result, channel_info] = ... 0012 % vb_load_sensor(megfile); 0013 % 2. Load all sensors including inactive sensors. 0014 % active_swt = false; 0015 % [pick, Qpick, CoilWeight, Vcenter, result, channel_info] = ... 0016 % vb_load_sensor(megfile, [], [], active_swt); 0017 % 0018 % [input] 0019 % megfile : <required> <<file>> MEG-MAT file or EEG-MAT file 0020 % ch_type : <optional> <<string>> channel type [''] 0021 % : '' or 'MEG' : MEG channels of MEG 0022 % : 'REF' : REFFERENCE channels of MEG 0023 % : 'ALL' : MEG + REFFERENCE channels of MEG 0024 % : 'MAG' : magnetometer channels 0025 % : 'AXIAL' : axial channels 0026 % : 'PLANAR' : planar channels 0027 % : 'MAG_X' : Magnetometer OPM channel data toward X-axis (only QZFM device) 0028 % : 'MAG_Y' : Magnetometer OPM channel data toward Y-axis (only QZFM device) 0029 % : 'MAG_Z' : Magnetometer OPM channel data toward Z-axis (only QZFM device) 0030 % : case-insensitive 0031 % ch_name : <optional> <<cell array>> channel name list [{''}(empty)] 0032 % : If ch_type is specified, this is ignored. 0033 % active_swt : <optional> <<boolean>> switch to filter channel 0034 % : if .ActiveChannel is valid [true] 0035 % : if .ActiveChannel is invalid [false] 0036 % : true) return only active channels 0037 % : false) return all the channels 0038 % method : <optional> method of calculation 0039 % : ['AVE'] : average 0040 % : 'TOP' : use top data 0041 % : this is valid for 'INIT' mode 0042 % [output] 0043 % pick : n-th coil position (Right-hand SPM coordinate) [m] 0044 % : [Ncoil x 3] 0045 % Qpick : n-th coil direction (Right-hand SPM coordinate) 0046 % : [Ncoil x 3] 0047 % CoilWeight : n-th coil weight for m-th channel [Nchannel x Ncoil] 0048 % : basis(channel,dipole) = CoilWeight * basis(coil,dipole) 0049 % Vcenter : Center of spherical head model [m] [1 x 3] 0050 % result : <<integer>> error infomation 0051 % : In the case that meg_file is '.info.mat' file and method is 0052 % : 'AVE', this will become error struct. 0053 % : fields are as follows: 0054 % : These are errors between base data of each file and average. 0055 % : .error_pick [n_ch x 3 x n_file] 0056 % : .error_Qpick [n_ch x 3 x n_file] (if they are) 0057 % channel_info : <<struct>> channel information of loaded data. 0058 % : .Active [Nchannel x 1] 0059 % : .Name [Nchannel x 1] 0060 % : .Type [Nchannel x 1] 0061 % : .ID [Nchannel x 1] 0062 % : return empty when the loaded data contains reference sensor. 0063 % ('REF', 'ALL') 0064 % [note] 0065 % if megfile is SBI data file or EEG-MAT file, REFFERENCE channel is empty 0066 % 0067 % [Active channel/Active trial information] 0068 % * Place 0069 % load(megfile, 'MEGinfo'); % EEG case, MEGinfo -> EEGinfo 0070 % MEGInfo.ActiveChannel : Active channel list (boolean array) [Nchannelx 1] 0071 % .ActiveTrial : Active trial list (boolean array) [Nrepeat x 1] 0072 % * Inactivate channel/trial 0073 % load_spec.ActiveChannel = false; 0074 % load_spec.ActiveTrial = false; 0075 % [data] = vb_load_meg_data(meg_file, load_spec); % [Nchannel x Nsample x Ntrial] 0076 % MEGinfo.ActiveChannel = ones(size(data, 1), 1); % All channel active 0077 % MEGinfo.ActiveTrial = ones(size(data, 3), 1); % All trial active 0078 % 0079 % % Inactivate channel/trial 0080 % MEGinfo.ActiveChannel(N) = 0; % Inactive data(N, :, :) 0081 % MEGinfo.ActiveTrial(M) = 0; % Inactive data(:, :, M) 0082 % then save it. vb_save(megfile, 'MEGinfo'); 0083 % 0084 % [see also] 0085 % vb_megfile_get_sensor_position_by_name 0086 % vb_megfile_get_sensor_position_by_type 0087 % 0088 % [history] 0089 % 2006-11-01 (Sako) modified to be able to accept EEGinfo 0090 % 2007-07-24 (Sako) added channel mode 0091 % 2008-04-16 (Sako) added active_swt, result 0092 % 2008-06-04 (Sako) changed default value of active_swt 0093 % 2009-08-21 (????) supported 'INFO' as "Measurement" but 'mode' is ignored 0094 % 2010-08-24 (Sako) added method argument 0095 % 2011-06-02 (Sako) converted return values of vb_load_device to upper case 0096 % 2011-07-26 (Sako) changed mode to ch_type, added ch_name as arguments 0097 % 2017-03-06 (rhayashi) supported ch_type, ch_name for fileinfo format. 0098 % 2017-04-15 (rhayashi) bugfix:ActiveChannel field work correctly. 0099 % 2018-08-22 (Takeda) removed warning message about Vcenter and 0100 % supported NEUROMAG 0101 % 2022-06-03 (k_suzuki) supported QZFM 0102 % 2022-06-24 (k_suzuki) fixed bug when load Info file of QZFM device 0103 % 0104 % Copyright (C) 2011, ATR All Rights Reserved. 0105 % License : New BSD License(see VBMEG_LICENSE.txt) 0106 0107 % --- CHECK ARGUMENTS --- % 0108 if ~exist('megfile', 'var'), megfile = []; end 0109 if ~exist('ch_type', 'var'), ch_type = []; end 0110 if ~exist('ch_name', 'var'), ch_name = []; end 0111 if ~exist('active_swt', 'var'), active_swt = []; end 0112 if ~exist('method', 'var'), method = ''; end 0113 [megfile, ch_type, ch_name, active_swt, method, result] = ... 0114 inner_check_arguments(megfile, ch_type, ch_name, active_swt, method); 0115 0116 % --- MAIN PROCEDURE --------------------------------------------------------- % 0117 % 0118 pick = []; 0119 Qpick = []; 0120 CoilWeight = []; 0121 Vcenter = []; 0122 channel_info = []; 0123 0124 if result ~= 0 0125 return; 0126 end 0127 0128 func_ = mfilename; 0129 0130 measurement = vb_load_device(megfile); 0131 Measurement = upper(measurement); 0132 0133 % return variables 0134 % check measurement parameter 0135 switch Measurement 0136 case 'MEG' 0137 if ~isempty(ch_type) 0138 [pick, Qpick, CoilWeight, Vcenter, result, channel_info] = ... 0139 vb_megfile_get_sensor_position_by_type(megfile, ch_type, active_swt); 0140 0141 elseif ~isempty(ch_name) 0142 [pick, Qpick, CoilWeight, Vcenter, result, channel_info] = ... 0143 vb_megfile_get_sensor_position_by_name(megfile, ch_name, active_swt); 0144 0145 else 0146 error('(%s) Both ch_type and ch_name are invalid', mfilename); 0147 end 0148 0149 case 'EEG' 0150 % for EEG 0151 if strcmp(ch_type, 'REF') 0152 % return empty 0153 return; 0154 else 0155 [pick, Vcenter, result, channel_info] = vb_load_eeg_sensor(megfile, active_swt); 0156 return; 0157 end 0158 0159 case 'INFO' 0160 load(megfile, 'fileinfo'); 0161 0162 switch method 0163 case 'AVE' 0164 [pick, Qpick, CoilWeight, Vcenter, result] = ... 0165 inner_calc_average(fileinfo); 0166 case 'TOP' 0167 [pick, Qpick, CoilWeight, Vcenter, result] = ... 0168 vb_load_sensor(fileinfo.filename{1}, [], [], false); 0169 otherwise 0170 msg = sprintf('(%s) undefined method : %s --> average', ... 0171 'vb_load_sensor', method); 0172 vb_disp(msg); 0173 [pick, Qpick, CoilWeight, Vcenter, result] = ... 0174 inner_calc_average(fileinfo); 0175 end 0176 0177 % Loaded sensor info 0178 info = vb_load_measurement_info(megfile); 0179 ch_info = vb_info_get_channel_info(info); 0180 0181 % ch_info.ID : is IDs for loaded information(pick, Qpick, CoilWeight). 0182 % To access the fileinfo.channel_id data, search and find index of ch_info.ID 0183 if isfield(fileinfo, 'channel_id') 0184 active_ix = vb_util_get_index(ch_info.ID, fileinfo.channel_id); 0185 else 0186 active_ix = find(fileinfo.ActiveChannel == 1); 0187 end 0188 0189 % reset active information 0190 ch_info.Active = zeros(length(ch_info.ID), 1); 0191 ch_info.Active(active_ix) = true; 0192 0193 if active_swt 0194 chan_info_ix = active_ix; 0195 else 0196 chan_info_ix = [1:length(ch_info.ID)]'; 0197 end 0198 0199 % specified channel type and name 0200 chan_info_type = ch_info.Type(chan_info_ix); 0201 chan_info_name = ch_info.Name(chan_info_ix); 0202 0203 % 'chan_info_ix' modification by channel type 0204 ignore_ch_name = false; % alternative (both specified case: ch_type is used.) 0205 if strcmpi(ch_type, 'MAG') 0206 chan_info_ix = chan_info_ix(find(chan_info_type == 1)); % MAG = 1; 0207 ignore_ch_name = true; 0208 elseif strcmpi(ch_type, 'AXIAL') 0209 chan_info_ix = chan_info_ix(find(chan_info_type == 2)); % AXIAL = 2; 0210 ignore_ch_name = true; 0211 elseif strcmpi(ch_type, 'PLANAR') 0212 chan_info_ix = chan_info_ix(find(chan_info_type == 3)); % PLANAR = 3; 0213 ignore_ch_name = true; 0214 elseif strcmpi(ch_type, 'MAG_X') 0215 chan_info_ix = chan_info_ix(find(chan_info_type == 4)); % MAG_X = 4; 0216 ignore_ch_name = true; 0217 elseif strcmpi(ch_type, 'MAG_Y') 0218 chan_info_ix = chan_info_ix(find(chan_info_type == 5)); % MAG_Y = 5; 0219 ignore_ch_name = true; 0220 elseif strcmpi(ch_type, 'MAG_Z') 0221 chan_info_ix = chan_info_ix(find(chan_info_type == 6)); % MAG_Z = 6; 0222 ignore_ch_name = true; 0223 elseif strcmpi(ch_type, 'MEG') 0224 % fall through 0225 % NOTE:default ch_type is 'MEG' even if the data file is for EEG. 0226 else 0227 error('unknown channel type is supported. : %s', ch_type); 0228 end 0229 0230 % 'chan_info_ix' modification by channel name 0231 if ~isempty(ch_name) && ignore_ch_name == false 0232 ix = []; 0233 for k=1:length(ch_name) 0234 add_ix = strmatch(ch_name{k}, chan_info_name, 'exact'); 0235 if isempty(add_ix) 0236 % display not found channel name. 0237 fprintf('%s ', ch_name{k}); 0238 end 0239 ix = [ix; add_ix]; 0240 end 0241 if length(ix) ~= length(ch_name) 0242 fprintf('data not loaded.\n'); 0243 end 0244 chan_info_ix = chan_info_ix(ix); 0245 end 0246 0247 % get sensor info through the 'chan_info_ix'. 0248 if isempty(CoilWeight) 0249 pick = pick(chan_info_ix,:); 0250 else 0251 weight = CoilWeight(chan_info_ix,:); 0252 ix_coil = find( sum(abs(weight), 1) > 0); 0253 0254 pick = pick(ix_coil,:); 0255 Qpick = Qpick(ix_coil,:); 0256 CoilWeight = weight(:,ix_coil); 0257 end 0258 0259 % channel_info 0260 channel_info.Active = ch_info.Active(chan_info_ix); 0261 channel_info.Name = ch_info.Name(chan_info_ix); 0262 channel_info.Type = ch_info.Type(chan_info_ix); 0263 channel_info.ID = ch_info.ID(chan_info_ix); 0264 0265 otherwise 0266 msg = sprintf('(%s)unknown Measurement : %s', func_, Measurement); 0267 vb_disp(msg); 0268 result = 2; 0269 end 0270 0271 % --- solve empty center problem 0272 if isempty(Vcenter) && ~isempty(pick) 0273 Vcenter = sum(pick, 1) ./ size(pick, 1); 0274 end 0275 return; 0276 % 0277 % --- END OF MAIN PROCEDURE -------------------------------------------------- % 0278 0279 % --- INNER FUNCTIONS -------------------------------------------------------- % 0280 % 0281 % --- inner_check_arguments() 0282 % 0283 function [megfile, ch_type, ch_name, active_swt, method, result] = ... 0284 inner_check_arguments(megfile, ch_type, ch_name, active_swt, method) 0285 func_ = mfilename; 0286 result = 0; % success 0287 0288 if isempty(megfile) 0289 msg = sprintf('(%s)megfile is a required parameter', func_); 0290 vb_disp(msg); 0291 result = 1; % error code 1 means bad megfile 0292 return; 0293 end 0294 0295 if exist(megfile, 'file') ~= 2 0296 msg = sprintf('(%s)cannot find megfile : %s', func_, megfile); 0297 vb_disp(msg); 0298 result = 1; 0299 return; 0300 end 0301 0302 % --- ch_name must be a cell array 0303 if ischar(ch_name) 0304 ch_name = {ch_name}; 0305 end 0306 0307 if iscellstr(ch_name) && isempty(ch_name{1}) 0308 ch_name = []; 0309 end 0310 0311 if isempty(ch_type) 0312 if isempty(ch_name) 0313 ch_type = 'MEG'; 0314 end 0315 end 0316 0317 % case-insensitive 0318 ch_type = upper(ch_type); 0319 0320 if isempty(active_swt) 0321 if vb_msrmnt_active_channel_is_valid(megfile) 0322 active_swt = true; 0323 else 0324 active_swt = false; 0325 end 0326 end 0327 0328 if isempty(method) 0329 method = 'AVE'; 0330 end 0331 method = upper(method); 0332 return; 0333 % 0334 % --- end of inner_check_arguments() 0335 0336 % --- inner_calc_average() 0337 % 0338 function [pick, Qpick, CoilWeight, Vcenter, result] = ... 0339 inner_calc_average(fileinfo) 0340 % 0341 n_file = length(fileinfo.filename); 0342 0343 pick = 0; 0344 Qpick = 0; 0345 CoilWeight = 0; 0346 Vcenter = 0; 0347 0348 for i_file = 1:n_file 0349 cur_file = fileinfo.filename{i_file}; 0350 [a, b, c, d] = vb_load_sensor(cur_file, [], [], false); 0351 0352 pick = pick + a; 0353 Qpick = Qpick + b; 0354 CoilWeight = CoilWeight + c; 0355 Vcenter = Vcenter + d; 0356 end 0357 0358 pick = pick / n_file; 0359 Qpick = Qpick / n_file; 0360 CoilWeight = CoilWeight / n_file; 0361 Vcenter = Vcenter / n_file; 0362 0363 error_pick = zeros(size(pick,1), size(pick,2), n_file); 0364 error_Qpick = zeros(size(Qpick,1), size(Qpick,2), n_file); 0365 0366 % --- error 0367 for i_file = 1:n_file 0368 cur_file = fileinfo.filename{i_file}; 0369 [a, b, c, d] = vb_load_sensor(cur_file, [], [], false); 0370 error_pick(:,:,i_file) = pick - a; 0371 error_Qpick(:,:,i_file) = Qpick - b; 0372 end 0373 0374 result = struct; 0375 result.error_pick = error_pick; 0376 result.error_Qpick = error_Qpick; 0377 return; 0378 % 0379 % --- end of inner_calc_average() 0380 % 0381 % --- END OF INNER FUNCTIONS ------------------------------------------------- %