emse_read_elp - Read an EMSE probe file (*.elp) Usage: elp = emse_read_elp(filename) This script extracts x,y,z values from an EMSE probe (*.elp) file, only if it contains EEG electrodes. EMSE *.elp files are in meters. Also, when using EMSE *.elp files in the eeg_toolbox, it is necessary to swap X and Y. This is handled by elec_open An example of the elp struct returned follows: version: 3 filetype: 2 minor_rev: 1 sensorType: 4001 sensorN: 125 nasion: [0.0957 0 0] lpa: [-7.1503e-004 0.0804 0] rpa: [7.1503e-004 -0.0804 0] x: [124x1 double] y: [124x1 double] z: [124x1 double] ref: [0.0089 -0.0732 -0.0214] origin: [-0.0083 0.0043 0.0496] type: {124x1 cell} name: {124x1 cell} See also: ELEC_OPEN, ELEC_LOAD
0001 function elp = emse_read_elp(filename) 0002 0003 % emse_read_elp - Read an EMSE probe file (*.elp) 0004 % 0005 % Usage: elp = emse_read_elp(filename) 0006 % 0007 % This script extracts x,y,z values from an EMSE 0008 % probe (*.elp) file, only if it contains EEG 0009 % electrodes. 0010 % 0011 % EMSE *.elp files are in meters. Also, when using 0012 % EMSE *.elp files in the eeg_toolbox, it is necessary 0013 % to swap X and Y. This is handled by elec_open 0014 % 0015 % An example of the elp struct returned follows: 0016 % 0017 % version: 3 0018 % filetype: 2 0019 % minor_rev: 1 0020 % sensorType: 4001 0021 % sensorN: 125 0022 % nasion: [0.0957 0 0] 0023 % lpa: [-7.1503e-004 0.0804 0] 0024 % rpa: [7.1503e-004 -0.0804 0] 0025 % x: [124x1 double] 0026 % y: [124x1 double] 0027 % z: [124x1 double] 0028 % ref: [0.0089 -0.0732 -0.0214] 0029 % origin: [-0.0083 0.0043 0.0496] 0030 % type: {124x1 cell} 0031 % name: {124x1 cell} 0032 % 0033 % See also: ELEC_OPEN, ELEC_LOAD 0034 % 0035 0036 % $Revision: 1.1 $ $Date: 2005/07/12 21:21:17 $ 0037 0038 % Licence: GNU GPL, no express or implied warranties 0039 % History: 10/2002, Darren.Weber_at_radiology.ucsf.edu 0040 % 0041 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 0042 0043 [path,name,ext] = fileparts(filename); 0044 file = fullfile(path,[name ext]); 0045 0046 [fid,msg] = fopen(file,'r'); 0047 if ~isempty(msg), error(msg); end 0048 0049 ver = '$Revision: 1.1 $'; 0050 fprintf('\nEMSE_READ_ELP [v %s]\n',ver(11:15)); 0051 fprintf('...reading .elp data.\n'); 0052 0053 tic 0054 0055 elp = read_elp(fid); 0056 0057 t = toc; fprintf('done (%6.2f sec).\n',t); 0058 0059 return 0060 0061 0062 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 0063 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 0064 function [elp] = read_elp(fid) 0065 0066 elp = []; 0067 0068 % Probe files contain position information for electrode locations 0069 % and/or gradiometer locations. The file consists of a prolog, a 0070 % header, and a list of one or more sensor fields. 0071 0072 % Any line beginning with '//' is a comment line, which is ignored 0073 0074 % Read the prolog 0075 tmp = fscanf(fid,'%d',3); 0076 elp.version = tmp(1); 0077 elp.filetype = tmp(2); % type 2 is a probe file, extension .elp 0078 elp.minor_rev = tmp(3); % usually 1 0079 0080 % Read the header 0081 % The header consists of one optional entry and 2 entries in 0082 % mandatory sequence and one optional entry: 0083 % Name [optional] > %N %s replace %s with name string (8 or fewer characters) 0084 % Type Code > %x replace %x with 1 (all electric), 2 (all magnetic) or 4 (mixed). 0085 % #Channels > %d number of points per channel per epoch 0086 0087 % Sensor state (which appears in the 'type code' field) may 0088 % be obtained by logically OR-ing suitable combinations from 0089 % Table A-3. Note that not all combinations are physically valid. 0090 % 0091 % type/state type code 0092 % magnetic 200 0093 % electric 400 0094 % off 800 0095 % reference 1000 0096 % optical 4000 0097 % trigger 8000 0098 % other 10000 0099 % named point 20000 0100 0101 % Other types (such as named points, trigger, and optical) should 0102 % be represented in the same pattern as electrodes, with the type 0103 % code set to identify the type. Even those types (e.g. trigger) 0104 % which do not have a true location, should have a nominal 0105 % location, (e.g. 0 0 0). 0106 0107 while 1, 0108 tmp = fgetl(fid); % This should be: //TypeCode nsensors 0109 if strmatch('//TypeCode',tmp), 0110 tmp = fscanf(fid,'%d',2); 0111 elp.sensorType = tmp(1); 0112 elp.sensorN = tmp(2); 0113 break; 0114 end 0115 end 0116 0117 % Fiducial points may be included optionally. They are required 0118 % for MRI registration. If they are included, they must be in 0119 % the obligatory order : nasion, left preauricular point, 0120 % right preauricular point. Table A-2 defines the format for 0121 % representing fiduciary points. 0122 0123 n = 0; 0124 while n <= 2, 0125 n = n + 1; 0126 tmp = fgetl(fid); % This should be: //Fiducials: Nasion Left Right 0127 if strmatch('//Fiducials',tmp), 0128 tmp = fgetl(fid); 0129 tmp = sscanf(tmp,'%2c %f %f %f'); 0130 elp.nasion = [tmp(3) tmp(4) tmp(5)]; 0131 tmp = fgetl(fid); 0132 tmp = sscanf(tmp,'%2c %f %f %f'); 0133 elp.lpa = [tmp(3) tmp(4) tmp(5)]; 0134 tmp = fgetl(fid); 0135 tmp = sscanf(tmp,'%2c %f %f %f'); 0136 elp.rpa = [tmp(3) tmp(4) tmp(5)]; 0137 break; 0138 end 0139 end 0140 0141 elp.x = zeros(elp.sensorN - 1,1); 0142 elp.y = zeros(elp.sensorN - 1,1); 0143 elp.z = zeros(elp.sensorN - 1,1); 0144 elp.ref = []; 0145 elp.origin = []; 0146 0147 n = 1; 0148 while n <= elp.sensorN, 0149 0150 tmp = fgetl(fid); 0151 if ~ischar(tmp), 0152 break; 0153 elseif strmatch('//',tmp); 0154 % Ignore the comment lines, get the next one 0155 tmp = fgetl(fid); 0156 end 0157 0158 % Each electrode is represented by an electric sensor, 0159 % and consists of 5 fields, of which 1 (the name) is 0160 % optional. The electric sensor field data is shown 0161 % in Table A-6. 0162 % Name Format Description 0163 % Type Code %S %x replace %x with 400 (electrode) or 1c00 if reference channel 0164 % Name [optional] %N %s replace %s with name string (8 or fewer characters) 0165 % Position %g %g %g electrode location with respect to head frame (Cartesian, meters) 0166 % Orientation %g %g %g not used, replace with 0 0 1 0167 0168 if strmatch('%S',tmp), 0169 0170 if findstr('c00',tmp), 0171 ref = 1; % A reference sensor 0172 else 0173 ref = 0; 0174 %tmp = sscanf(tmp,'%2c %d'); 0175 elp.type{n,1} = tmp(4:end); 0176 end 0177 0178 tmp = fgetl(fid); 0179 if strmatch('//',tmp); 0180 % Ignore the comment lines, get the next one 0181 tmp = fgetl(fid); 0182 end 0183 0184 tmp = deblank(tmp); 0185 if strmatch('%N',tmp), 0186 0187 % Read the name of the sensor 0188 tmp = strrep(tmp,'%N',''); 0189 tmp = fliplr(deblank(fliplr(tmp))); 0190 if ~ref, elp.name{n,1} = tmp; end 0191 0192 % Read the location XYZ 0193 tmp = fgetl(fid); 0194 if strmatch('//',tmp); 0195 % Ignore comments, get the next line 0196 tmp = fgetl(fid); 0197 end 0198 0199 if strmatch('%O',tmp), 0200 if isempty(elp.origin), 0201 % Get the sphere origin 0202 elp.origin = sscanf(tmp(3:end),'%f',3)'; 0203 end 0204 tmp = fgetl(fid); 0205 tmp = fgetl(fid); 0206 % Read the xyz location 0207 tmp = sscanf(tmp,'%f',3); 0208 if ref, 0209 elp.ref = tmp'; 0210 else 0211 elp.x(n) = tmp(1); 0212 elp.y(n) = tmp(2); 0213 elp.z(n) = tmp(3); 0214 n = n + 1; 0215 end 0216 % Skip the next line (empty) 0217 tmp = fgetl(fid); 0218 else 0219 tmp = sscanf(tmp,'%f',3); 0220 if ref, 0221 elp.ref = tmp'; 0222 else 0223 elp.x(n) = tmp(1); 0224 elp.y(n) = tmp(2); 0225 elp.z(n) = tmp(3); 0226 n = n + 1; 0227 end 0228 end 0229 end 0230 end 0231 end 0232 0233 fclose(fid); 0234 0235 return 0236 0237 0238 0239 0240 %##################################################### 0241 %# Declarations 0242 % 0243 %@miss = ("LEFT", "VEOGR", "HEOG", "NA1"); 0244 % 0245 %@landmarks = ("Nasion", "Left", "Right", "Centroid", "Ref"); 0246 % 0247 %##################################################### 0248 %# Output to STDOUT 0249 0250 %@d = split(/\s+/, $dat{"Nasion"}); 0251 %$name = "Nasion"; 0252 %$code = 110; 0253 %printf "%10s\t%d\t%12.6f\t%12.6f\t%12.6f\n",$name,$code,($d[2] * -100),($d[1] * 100),($d[3] * 100); 0254 0255 %@d = split(/\s+/, $dat{"Left"}); 0256 %$name = "Left"; 0257 %$code = 108; 0258 %printf "%10s\t%d\t%12.6f\t%12.6f\t%12.6f\n",$name,$code,($d[2] * -100),($d[1] * 100),($d[3] * 100); 0259 0260 %@d = split(/\s+/, $dat{"Right"}); 0261 %$name = "Right"; 0262 %$code = 114; 0263 %printf "%10s\t%d\t%12.6f\t%12.6f\t%12.6f\n",$name,$code,($d[2] * -100),($d[1] * 100),($d[3] * 100); 0264 0265 %foreach $k ( sort {$a<=>$b} keys (%dat) ){ 0266 0267 % $pr = "yes"; 0268 0269 % # Skip various points defined above in @miss and @landmarks 0270 % foreach $m (@miss, @landmarks) { 0271 % if ($k =~ /$m/i) { $pr = "no"; } 0272 % } 0273 0274 % # otherwise, print ordered list of points 0275 % if($pr eq "yes"){ 0276 0277 % #Output normal electrode positions 0278 0279 % @d = split(/\s+/, $dat{$k}); 0280 % $code = 69; 0281 % printf "%10s\t%d\t%12.6f\t%12.6f\t%12.6f\n",$k,$code,($d[2] * -100),($d[1] * 100),($d[3] * 100); 0282 0283 0284 %#Output centroid and ref points 0285 0286 %@d = split(/\s+/, $dat{"Centroid"}); 0287 %$name = "Centroid"; 0288 %$code = 99; 0289 %printf "%10s\t%d\t%12.6f\t%12.6f\t%12.6f\n",$name,$code,($d[2] * -100),($d[1] * 100),($d[3] * 100); 0290 0291 %@d = split(/\s+/, $dat{"Ref"}); 0292 %$name = "Ref"; 0293 %$code = 120; 0294 %printf "%10s\t%d\t%12.6f\t%12.6f\t%12.6f\n",$name,$code,($d[2] * -100),($d[1] * 100),($d[3] * 100);