Home > eeg > fixes > readlocs.m

readlocs

PURPOSE ^

readlocs() - read electrode location coordinates and other information from a file.

SYNOPSIS ^

function [eloc, labels, theta, radius, indices] = readlocs( filename, varargin );

DESCRIPTION ^

 readlocs() - read electrode location coordinates and other information from a file. 
              Several standard file formats are supported. Users may also specify 
              a custom column format. Defined format examples are given below 
              (see File Formats).
 Usage:
   >>  eloc = readlocs( filename );
   >>  EEG.chanlocs = readlocs( filename, 'key', 'val', ... ); 
   >>  [eloc, labels, theta, radius, indices] = ...
                                               readlocs( filename, 'key', 'val', ... );
 Inputs:
   filename   - Name of the file containing the electrode locations
                {default: 2-D polar coordinates} (see >> help topoplot )

 Optional inputs:
   'filetype'  - ['loc'|'sph'|'sfp'|'xyz'|'asc'|'polhemus'|'besa'|'chanedit'|'custom'] 
                 Type of the file to read. By default the file type is determined 
                 using the file extension (see below under File Formats):
                  'loc' - an EEGLAB 2-D polar coordinates channel locations file 
                          Coordinates are theta and radius (see definitions below).
                  'sph' - Matlab spherical coordinates (Note: spherical
                          coordinates used by Matlab functions are different 
                          from spherical coordinates used by BESA - see below).
                  'sfp' - EGI Cartesian coordinates (NOT Matlab Cartesian - see below).
                  'xyz' - Matlab/EEGLAB Cartesian coordinates (NOT EGI Cartesian).
                          z is toward nose; y is toward left ear; z is toward vertex
                  'asc' - Neuroscan polar coordinates.
                  'polhemus' or 'polhemusx' - Polhemus electrode location file recorded 
                          with 'X' on sensor pointing to subject (see below and readelp()).
                  'polhemusy' - Polhemus electrode location file recorded with 
                          'Y' on sensor pointing to subject (see below and readelp()).
                  'besa' - BESA-'.elp' spherical coordinates. (Not MATLAB spherical -
                           see below).
                  'chanedit' - EEGLAB channel location file created by pop_chanedit().
                  'custom' - Ascii file with columns in user-defined 'format' (see below).
   'importmode' - ['eeglab'|'native'] for location files containing 3-D cartesian electrode
                  coordinates, import either in EEGLAB format (nose pointing toward +X). 
                  This may not always be possible since EEGLAB might not be able to 
                  determine the nose direction for scanned electrode files. 'native' import
                  original carthesian coordinates (user can then specify the position of
                  the nose when calling the topoplot() function; in EEGLAB the position
                  of the nose is stored in the EEG.chaninfo structure). {default 'eeglab'}
   'format'    - [cell array] Format of a 'custom' channel location file (see above).
                          {default: if no file type is defined. The cell array contains
                          labels defining the meaning of each column of the input file:
                           'channum'   [positive integer] channel number 
                           'labels'    [string] channel name (no spaces)
                           'theta'     [real degrees] 2-D angle in polar coordinates; 
                                       positive = rotating from nose (0) toward left ear 
                           'radius'    [real] radius for 2-D polar coords; 0.5 is the head 
                                       disk radius and limit for topoplot() plotting)
                           'X'         [real] Matlab-Cartesian X coordinate (to nose)
                           'Y'         [real] Matlab-Cartesian Y coordinate (to left ear)
                           'Z'         [real] Matlab-Cartesian Z coordinate (to vertex)
                           '-X','-Y','-Z' Matlab-Cartesian coordinates pointing opposite
                                       to the above.
                           'sph_theta' [real degrees] Matlab spherical horizontal angle; 
                                       positive = rotating from nose (0) toward left ear.
                           'sph_phi'   [real degrees] Matlab spherical elevation angle;
                                       positive = rotating from horizontal (0) upwards.
                           'sph_radius' [real] distance from head center (unused) 
                           'sph_phi_besa' [real degrees] BESA phi angle from vertical; 
                                       positive = rotating from vertex (0) towards right ear.
                           'sph_theta_besa' [real degrees] BESA theta horiz/azimuthal angle; 
                                       positive = rotating from right ear (0) toward nose.
                           'ignore'    ignore column}
     The input file may also contain other channel information fields
                           'type'      channel type: 'EEG', 'MEG', 'EMG', 'ECG', others ...
                           'calib'     [real near 1.0] channel calibration value.
                           'gain'      [real > 1] channel gain. 
                           'custom1'   custom field #1.
                           'custom2', 'custom3', 'custom4', etc.    more custom fields
   'skiplines' - [integer] Number of header lines to skip (in 'custom' file types only).
                 Note: Characters on a line following '%' will be treated as comments.
   'readchans' - [integer array] indices of electrodes to read. {default: all}
   'center'    - [(1,3) real array or 'auto'] center of xyz coordinates for conversion 
                 to spherical or polar, Specify the center of the sphere here, or 'auto'. 
                 This uses the center of the sphere that best fits all the electrode 
                 locations read. {default: [0 0 0]}
 Outputs:
   eloc        - structure containing the channel names and locations (if present).
                 It has three fields: 'eloc.labels', 'eloc.theta' and 'eloc.radius' 
                 identical in meaning to the EEGLAB struct 'EEG.chanlocs'.
   labels      - cell array of strings giving the names of the electrodes. NOTE: Unlike the
                 three outputs below, includes labels of channels *without* location info.
   theta       - vector (in degrees) of polar angles of the electrode locations.
   radius      - vector of polar-coordinate radii (arc_lengths) of the electrode locations 
   indices     - indices, k, of channels with non-empty 'locs(k).theta' coordinate

 File formats:
   If 'filetype' is unspecified, the file extension determines its type.

   '.loc' or '.locs' or '.eloc': 
               polar coordinates. Notes: angles in degrees: 
               right ear is 90; left ear -90; head disk radius is 0.5. 
               Fields:   N    angle  radius    label
               Sample:   1    -18    .511       Fp1   
                         2     18    .511       Fp2  
                         3    -90    .256       C3
                         4     90    .256       C4
                           ...
               Note: In previous releases, channel labels had to contain exactly 
               four characters (spaces replaced by '.'). This format still works, 
               though dots are no longer required.
   '.sph':
               Matlab spherical coordinates. Notes: theta is the azimuthal/horizontal angle
               in deg.: 0 is toward nose, 90 rotated to left ear. Following this, performs
               the elevation (phi). Angles in degrees.
               Fields:   N    theta    phi    label
               Sample:   1      18     -2      Fp1
                         2     -18     -2      Fp2
                         3      90     44      C3
                         4     -90     44      C4
                           ...
   '.elc':
               Cartesian 3-D electrode coordinates scanned using the EETrak software. 
               See readeetraklocs().
   '.elp':     
               Polhemus-.'elp' Cartesian coordinates. By default, an .elp extension is read
               as PolhemusX-elp in which 'X' on the Polhemus sensor is pointed toward the 
               subject. Polhemus files are not in columnar format (see readelp()).
   '.elp':
               BESA-'.elp' spherical coordinates: Need to specify 'filetype','besa'.
               The elevation angle (phi) is measured from the vertical axis. Positive 
               rotation is toward right ear. Next, perform azimuthal/horizontal rotation 
               (theta): 0 is toward right ear; 90 is toward nose, -90 toward occiput. 
               Angles are in degrees.  If labels are absent or weights are given in 
               a last column, readlocs() adjusts for this. Default labels are E1, E2, ...
               Fields:   label      phi  theta   
               Sample:   Fp1        -92   -72    
                         Fp2         92    72   
                         C3         -46    0  
                         C4          46    0 
                           ...
   '.xyz': 
               Matlab/EEGLAB Cartesian coordinates. Here. x is towards the nose, 
               y is towards the left ear, and z towards the vertex.
               Fields:   channum   x           y         z     label
               Sample:   1       .950        .308     -.035     Fp1
                         2       .950       -.308     -.035     Fp2
                         3        0           .719      .695    C3
                         4        0          -.719      .695    C4
                           ...
   '.asc', '.dat':     
               Neuroscan-.'asc' or '.dat' Cartesian polar coordinates text file.
   '.sfp': 
               BESA/EGI-xyz Cartesian coordinates. Notes: For EGI, x is toward right ear, 
               y is toward the nose, z is toward the vertex. EEGLAB converts EGI 
               Cartesian coordinates to Matlab/EEGLAB xyz coordinates. 
               Fields:   label   x           y          z
               Sample:   Fp1    -.308        .950      -.035    
                         Fp2     .308        .950      -.035  
                         C3     -.719        0          .695  
                         C4      .719        0          .695  
                           ...
   '.ced':   
               ASCII file saved by pop_chanedit(). Contains multiple MATLAB/EEGLAB formats.
               Cartesian coordinates are as in the 'xyz' format (above).
               Fields:   channum  label  theta  radius   x      y      z    sph_theta   sph_phi  ...
               Sample:   1        Fp1     -18    .511   .950   .308  -.035   18         -2       ...
                         2        Fp2      18    .511   .950  -.308  -.035  -18         -2       ...
                         3        C3      -90    .256   0      .719   .695   90         44       ...
                         4        C4       90    .256   0     -.719   .695  -90         44       ...
                           ...
               The last columns of the file may contain any other defined fields (gain,
               calib, type, custom).

 Author: Arnaud Delorme, Salk Institute, 8 Dec 2002 (expanded from the previous EEG/ICA 
         toolbox function)

 See also: readelp(), writelocs(), topo2sph(), sph2topo(), sph2cart()

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SUBFUNCTIONS ^

SOURCE CODE ^

0001 % readlocs() - read electrode location coordinates and other information from a file.
0002 %              Several standard file formats are supported. Users may also specify
0003 %              a custom column format. Defined format examples are given below
0004 %              (see File Formats).
0005 % Usage:
0006 %   >>  eloc = readlocs( filename );
0007 %   >>  EEG.chanlocs = readlocs( filename, 'key', 'val', ... );
0008 %   >>  [eloc, labels, theta, radius, indices] = ...
0009 %                                               readlocs( filename, 'key', 'val', ... );
0010 % Inputs:
0011 %   filename   - Name of the file containing the electrode locations
0012 %                {default: 2-D polar coordinates} (see >> help topoplot )
0013 %
0014 % Optional inputs:
0015 %   'filetype'  - ['loc'|'sph'|'sfp'|'xyz'|'asc'|'polhemus'|'besa'|'chanedit'|'custom']
0016 %                 Type of the file to read. By default the file type is determined
0017 %                 using the file extension (see below under File Formats):
0018 %                  'loc' - an EEGLAB 2-D polar coordinates channel locations file
0019 %                          Coordinates are theta and radius (see definitions below).
0020 %                  'sph' - Matlab spherical coordinates (Note: spherical
0021 %                          coordinates used by Matlab functions are different
0022 %                          from spherical coordinates used by BESA - see below).
0023 %                  'sfp' - EGI Cartesian coordinates (NOT Matlab Cartesian - see below).
0024 %                  'xyz' - Matlab/EEGLAB Cartesian coordinates (NOT EGI Cartesian).
0025 %                          z is toward nose; y is toward left ear; z is toward vertex
0026 %                  'asc' - Neuroscan polar coordinates.
0027 %                  'polhemus' or 'polhemusx' - Polhemus electrode location file recorded
0028 %                          with 'X' on sensor pointing to subject (see below and readelp()).
0029 %                  'polhemusy' - Polhemus electrode location file recorded with
0030 %                          'Y' on sensor pointing to subject (see below and readelp()).
0031 %                  'besa' - BESA-'.elp' spherical coordinates. (Not MATLAB spherical -
0032 %                           see below).
0033 %                  'chanedit' - EEGLAB channel location file created by pop_chanedit().
0034 %                  'custom' - Ascii file with columns in user-defined 'format' (see below).
0035 %   'importmode' - ['eeglab'|'native'] for location files containing 3-D cartesian electrode
0036 %                  coordinates, import either in EEGLAB format (nose pointing toward +X).
0037 %                  This may not always be possible since EEGLAB might not be able to
0038 %                  determine the nose direction for scanned electrode files. 'native' import
0039 %                  original carthesian coordinates (user can then specify the position of
0040 %                  the nose when calling the topoplot() function; in EEGLAB the position
0041 %                  of the nose is stored in the EEG.chaninfo structure). {default 'eeglab'}
0042 %   'format'    - [cell array] Format of a 'custom' channel location file (see above).
0043 %                          {default: if no file type is defined. The cell array contains
0044 %                          labels defining the meaning of each column of the input file:
0045 %                           'channum'   [positive integer] channel number
0046 %                           'labels'    [string] channel name (no spaces)
0047 %                           'theta'     [real degrees] 2-D angle in polar coordinates;
0048 %                                       positive = rotating from nose (0) toward left ear
0049 %                           'radius'    [real] radius for 2-D polar coords; 0.5 is the head
0050 %                                       disk radius and limit for topoplot() plotting)
0051 %                           'X'         [real] Matlab-Cartesian X coordinate (to nose)
0052 %                           'Y'         [real] Matlab-Cartesian Y coordinate (to left ear)
0053 %                           'Z'         [real] Matlab-Cartesian Z coordinate (to vertex)
0054 %                           '-X','-Y','-Z' Matlab-Cartesian coordinates pointing opposite
0055 %                                       to the above.
0056 %                           'sph_theta' [real degrees] Matlab spherical horizontal angle;
0057 %                                       positive = rotating from nose (0) toward left ear.
0058 %                           'sph_phi'   [real degrees] Matlab spherical elevation angle;
0059 %                                       positive = rotating from horizontal (0) upwards.
0060 %                           'sph_radius' [real] distance from head center (unused)
0061 %                           'sph_phi_besa' [real degrees] BESA phi angle from vertical;
0062 %                                       positive = rotating from vertex (0) towards right ear.
0063 %                           'sph_theta_besa' [real degrees] BESA theta horiz/azimuthal angle;
0064 %                                       positive = rotating from right ear (0) toward nose.
0065 %                           'ignore'    ignore column}
0066 %     The input file may also contain other channel information fields
0067 %                           'type'      channel type: 'EEG', 'MEG', 'EMG', 'ECG', others ...
0068 %                           'calib'     [real near 1.0] channel calibration value.
0069 %                           'gain'      [real > 1] channel gain.
0070 %                           'custom1'   custom field #1.
0071 %                           'custom2', 'custom3', 'custom4', etc.    more custom fields
0072 %   'skiplines' - [integer] Number of header lines to skip (in 'custom' file types only).
0073 %                 Note: Characters on a line following '%' will be treated as comments.
0074 %   'readchans' - [integer array] indices of electrodes to read. {default: all}
0075 %   'center'    - [(1,3) real array or 'auto'] center of xyz coordinates for conversion
0076 %                 to spherical or polar, Specify the center of the sphere here, or 'auto'.
0077 %                 This uses the center of the sphere that best fits all the electrode
0078 %                 locations read. {default: [0 0 0]}
0079 % Outputs:
0080 %   eloc        - structure containing the channel names and locations (if present).
0081 %                 It has three fields: 'eloc.labels', 'eloc.theta' and 'eloc.radius'
0082 %                 identical in meaning to the EEGLAB struct 'EEG.chanlocs'.
0083 %   labels      - cell array of strings giving the names of the electrodes. NOTE: Unlike the
0084 %                 three outputs below, includes labels of channels *without* location info.
0085 %   theta       - vector (in degrees) of polar angles of the electrode locations.
0086 %   radius      - vector of polar-coordinate radii (arc_lengths) of the electrode locations
0087 %   indices     - indices, k, of channels with non-empty 'locs(k).theta' coordinate
0088 %
0089 % File formats:
0090 %   If 'filetype' is unspecified, the file extension determines its type.
0091 %
0092 %   '.loc' or '.locs' or '.eloc':
0093 %               polar coordinates. Notes: angles in degrees:
0094 %               right ear is 90; left ear -90; head disk radius is 0.5.
0095 %               Fields:   N    angle  radius    label
0096 %               Sample:   1    -18    .511       Fp1
0097 %                         2     18    .511       Fp2
0098 %                         3    -90    .256       C3
0099 %                         4     90    .256       C4
0100 %                           ...
0101 %               Note: In previous releases, channel labels had to contain exactly
0102 %               four characters (spaces replaced by '.'). This format still works,
0103 %               though dots are no longer required.
0104 %   '.sph':
0105 %               Matlab spherical coordinates. Notes: theta is the azimuthal/horizontal angle
0106 %               in deg.: 0 is toward nose, 90 rotated to left ear. Following this, performs
0107 %               the elevation (phi). Angles in degrees.
0108 %               Fields:   N    theta    phi    label
0109 %               Sample:   1      18     -2      Fp1
0110 %                         2     -18     -2      Fp2
0111 %                         3      90     44      C3
0112 %                         4     -90     44      C4
0113 %                           ...
0114 %   '.elc':
0115 %               Cartesian 3-D electrode coordinates scanned using the EETrak software.
0116 %               See readeetraklocs().
0117 %   '.elp':
0118 %               Polhemus-.'elp' Cartesian coordinates. By default, an .elp extension is read
0119 %               as PolhemusX-elp in which 'X' on the Polhemus sensor is pointed toward the
0120 %               subject. Polhemus files are not in columnar format (see readelp()).
0121 %   '.elp':
0122 %               BESA-'.elp' spherical coordinates: Need to specify 'filetype','besa'.
0123 %               The elevation angle (phi) is measured from the vertical axis. Positive
0124 %               rotation is toward right ear. Next, perform azimuthal/horizontal rotation
0125 %               (theta): 0 is toward right ear; 90 is toward nose, -90 toward occiput.
0126 %               Angles are in degrees.  If labels are absent or weights are given in
0127 %               a last column, readlocs() adjusts for this. Default labels are E1, E2, ...
0128 %               Fields:   label      phi  theta
0129 %               Sample:   Fp1        -92   -72
0130 %                         Fp2         92    72
0131 %                         C3         -46    0
0132 %                         C4          46    0
0133 %                           ...
0134 %   '.xyz':
0135 %               Matlab/EEGLAB Cartesian coordinates. Here. x is towards the nose,
0136 %               y is towards the left ear, and z towards the vertex.
0137 %               Fields:   channum   x           y         z     label
0138 %               Sample:   1       .950        .308     -.035     Fp1
0139 %                         2       .950       -.308     -.035     Fp2
0140 %                         3        0           .719      .695    C3
0141 %                         4        0          -.719      .695    C4
0142 %                           ...
0143 %   '.asc', '.dat':
0144 %               Neuroscan-.'asc' or '.dat' Cartesian polar coordinates text file.
0145 %   '.sfp':
0146 %               BESA/EGI-xyz Cartesian coordinates. Notes: For EGI, x is toward right ear,
0147 %               y is toward the nose, z is toward the vertex. EEGLAB converts EGI
0148 %               Cartesian coordinates to Matlab/EEGLAB xyz coordinates.
0149 %               Fields:   label   x           y          z
0150 %               Sample:   Fp1    -.308        .950      -.035
0151 %                         Fp2     .308        .950      -.035
0152 %                         C3     -.719        0          .695
0153 %                         C4      .719        0          .695
0154 %                           ...
0155 %   '.ced':
0156 %               ASCII file saved by pop_chanedit(). Contains multiple MATLAB/EEGLAB formats.
0157 %               Cartesian coordinates are as in the 'xyz' format (above).
0158 %               Fields:   channum  label  theta  radius   x      y      z    sph_theta   sph_phi  ...
0159 %               Sample:   1        Fp1     -18    .511   .950   .308  -.035   18         -2       ...
0160 %                         2        Fp2      18    .511   .950  -.308  -.035  -18         -2       ...
0161 %                         3        C3      -90    .256   0      .719   .695   90         44       ...
0162 %                         4        C4       90    .256   0     -.719   .695  -90         44       ...
0163 %                           ...
0164 %               The last columns of the file may contain any other defined fields (gain,
0165 %               calib, type, custom).
0166 %
0167 % Author: Arnaud Delorme, Salk Institute, 8 Dec 2002 (expanded from the previous EEG/ICA
0168 %         toolbox function)
0169 %
0170 % See also: readelp(), writelocs(), topo2sph(), sph2topo(), sph2cart()
0171 
0172 %123456789012345678901234567890123456789012345678901234567890123456789012
0173 
0174 % Copyright (C) Arnaud Delorme, CNL / Salk Institute, 28 Feb 2002
0175 %
0176 % This program is free software; you can redistribute it and/or modify
0177 % it under the terms of the GNU General Public License as published by
0178 % the Free Software Foundation; either version 2 of the License, or
0179 % (at your option) any later version.
0180 %
0181 % This program is distributed in the hope that it will be useful,
0182 % but WITHOUT ANY WARRANTY; without even the implied warranty of
0183 % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0184 % GNU General Public License for more details.
0185 %
0186 % You should have received a copy of the GNU General Public License
0187 % along with this program; if not, write to the Free Software
0188 % Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
0189 
0190 % $Log: readlocs.m,v $
0191 % Revision 1.87  2006/06/01 17:40:50  arno
0192 % updating header
0193 %
0194 % Revision 1.86  2006/05/26 15:59:35  scott
0195 % worked on text of instructions for adding a channel type -- NOTE: chaninfo is
0196 % discussed in help message, but NOT implemented!?
0197 %
0198 % Revision 1.85  2006/04/14 21:19:08  arno
0199 % fixing skipping lines
0200 %
0201 % Revision 1.84  2006/03/31 03:11:13  toby
0202 % made '.eloc' equivalent to '.loc' as a filetype
0203 %
0204 % Revision 1.83  2006/02/14 00:01:18  arno
0205 % change xyz format
0206 %
0207 % Revision 1.82  2006/01/20 22:37:08  arno
0208 % default for BESA and polhemus
0209 %
0210 % Revision 1.81  2006/01/12 23:22:39  arno
0211 % fixing indices
0212 %
0213 % Revision 1.80  2006/01/12 22:03:51  arno
0214 % fiducial type
0215 %
0216 % Revision 1.79  2006/01/10 22:56:17  arno
0217 % adding defaultelp option
0218 %
0219 % Revision 1.78  2006/01/10 22:53:49  arno
0220 % [6~[6~changing default besa format
0221 %
0222 % Revision 1.77  2005/11/30 18:31:40  arno
0223 % same
0224 %
0225 % Revision 1.76  2005/11/30 18:29:48  arno
0226 % same
0227 %
0228 % Revision 1.75  2005/11/30 18:28:37  arno
0229 % reformat outputs
0230 %
0231 % Revision 1.74  2005/10/29 03:49:50  scott
0232 % NOTE: there  is no mention of 'chantype' - should at least add a help mention after line  69 -sm
0233 %
0234 % Revision 1.73  2005/09/27 22:08:41  arno
0235 % fixing reading .ced files
0236 %
0237 % Revision 1.72  2005/05/24 17:07:05  arno
0238 % cell2mat - celltomat
0239 %
0240 % Revision 1.71  2005/03/10 17:42:11  arno
0241 % new format for channel location info
0242 %
0243 % Revision 1.70  2005/03/08 23:19:24  arno
0244 % using old function to read asa format
0245 %
0246 % Revision 1.69  2005/03/04 23:17:22  arno
0247 % use fieldtrip readeetrack
0248 %
0249 % Revision 1.65  2004/10/27 01:01:05  arno
0250 % msg format
0251 %
0252 % Revision 1.64  2004/03/23 00:37:56  scott
0253 % clarifying help msg re meaning of 'indices' output
0254 %
0255 % Revision 1.63  2004/03/23 00:22:51  scott
0256 % clarified meaning of output 'indices'
0257 %
0258 % Revision 1.62  2004/02/24 17:17:32  arno
0259 % dbug message
0260 %
0261 % Revision 1.61  2004/01/01 19:12:08  scott
0262 % help message edits
0263 %
0264 % Revision 1.60  2004/01/01 18:57:26  scott
0265 % edit text outputs
0266 %
0267 % Revision 1.59  2004/01/01 01:47:34  scott
0268 % franglais -> anglais
0269 %
0270 % Revision 1.58  2003/12/17 00:55:07  arno
0271 % debug last
0272 %
0273 % Revision 1.57  2003/12/17 00:50:10  arno
0274 % adding index for non-empty electrodes
0275 %
0276 % Revision 1.56  2003/12/05 18:37:56  arno
0277 % debug polhemus x and y fixed
0278 %
0279 % Revision 1.55  2003/12/02 03:21:39  arno
0280 % neuroscan format
0281 %
0282 % Revision 1.54  2003/11/27 00:38:13  arno
0283 % conversion elc
0284 %
0285 % Revision 1.53  2003/11/27 00:31:30  arno
0286 % debuging elc format
0287 %
0288 % Revision 1.52  2003/11/27 00:25:51  arno
0289 % automatically detecting elc files
0290 %
0291 % Revision 1.51  2003/11/05 17:20:23  arno
0292 % first convert spherical instead of carthesian
0293 %
0294 % Revision 1.50  2003/09/18 00:07:05  arno
0295 % further checks for neuroscan
0296 %
0297 % Revision 1.49  2003/07/16 18:52:21  arno
0298 % allowing file type locs
0299 %
0300 % Revision 1.48  2003/06/30 15:00:43  arno
0301 % fixing inputcheck problem
0302 %
0303 % Revision 1.47  2003/05/13 23:31:25  arno
0304 % number of lines to skip in chanedit format
0305 %
0306 % Revision 1.46  2003/05/13 22:09:01  arno
0307 % updating sph format
0308 %
0309 % Revision 1.45  2003/05/13 22:07:07  arno
0310 % removing labels in sfp format
0311 %
0312 % Revision 1.44  2003/05/13 21:14:11  arno
0313 % only write a subset of file format
0314 %
0315 % Revision 1.43  2003/03/10 16:28:12  arno
0316 % removing help for elc
0317 %
0318 % Revision 1.42  2003/03/10 16:26:59  arno
0319 % adding then removing .elc format
0320 %
0321 % Revision 1.41  2003/03/08 17:36:13  arno
0322 % import spherical EGI files correctly
0323 %
0324 % Revision 1.40  2003/03/05 15:38:15  arno
0325 % fixing '.' bug
0326 %
0327 % Revision 1.39  2003/03/04 20:04:44  arno
0328 % adding neuroscan .asc format
0329 %
0330 % Revision 1.38  2003/01/30 16:45:12  arno
0331 % debugging ced format
0332 %
0333 % Revision 1.37  2003/01/10 17:40:11  arno
0334 % removing trailing dots
0335 %
0336 % Revision 1.36  2003/01/03 22:47:00  arno
0337 % typo in warning messages
0338 %
0339 % Revision 1.35  2003/01/03 22:45:48  arno
0340 % adding another warning message
0341 %
0342 % Revision 1.34  2003/01/03 22:41:38  arno
0343 % autodetect format .sfp
0344 %
0345 % Revision 1.33  2003/01/03 22:38:39  arno
0346 % adding warning message
0347 %
0348 % Revision 1.32  2002/12/29 23:04:00  scott
0349 % header
0350 %
0351 % Revision 1.31  2002/12/29 22:37:15  arno
0352 % txt -> ced
0353 %
0354 % Revision 1.30  2002/12/29 22:35:35  arno
0355 % adding coords. info for file format in header, programming .sph, ...
0356 %
0357 % Revision 1.29  2002/12/29 22:00:10  arno
0358 % skipline -> skiplines
0359 %
0360 % Revision 1.28  2002/12/28 23:46:45  scott
0361 % header
0362 %
0363 % Revision 1.27  2002/12/28 02:02:35  scott
0364 % header details
0365 %
0366 % Revision 1.26  2002/12/28 01:32:41  scott
0367 % worked on header information - axis details etcetc. -sm & ad
0368 %
0369 % Revision 1.25  2002/12/27 23:23:35  scott
0370 % edit header msg - NEEDS MORE DETAILS -sm
0371 %
0372 % Revision 1.24  2002/12/27 22:57:23  arno
0373 % debugging polhemus
0374 %
0375 % Revision 1.23  2002/12/27 17:47:32  arno
0376 % compatible with more BESA formats
0377 %
0378 % Revision 1.22  2002/12/26 16:41:23  arno
0379 % new release
0380 %
0381 % Revision 1.21  2002/12/24 02:51:22  arno
0382 % new version of readlocs
0383 %
0384 
0385 
0386 function [eloc, labels, theta, radius, indices] = readlocs( filename, varargin ); 
0387 
0388 if nargin < 1
0389     help readlocs;
0390     return;
0391 end;
0392 
0393 % NOTE: To add a new channel format:
0394 % ----------------------------------
0395 % 1) Add a new element to the structure 'chanformat' (see 'ADD NEW FORMATS HERE' below):
0396 % 2)  Enter a format 'type' for the new file format,
0397 % 3)  Enter a (short) 'typestring' description of the format
0398 % 4)  Enter a longer format 'description' (possibly multiline, see ex. (1) below)
0399 % 5)  Enter format file column labels in the 'importformat' field (see ex. (2) below)
0400 % 6)  Enter the number of header lines to skip (if any) in the 'skipline' field
0401 % 7)  Document the new channel format in the help message above.
0402 % 8)  After testing, please send the new version of readloca.m to us
0403 %       at eeglab@sccn.ucsd.edu with a sample locs file.
0404 % The 'chanformat' structure is also used (automatically) by the writelocs()
0405 % and pop_readlocs() functions. You do not need to edit these functions.
0406 
0407 chanformat(1).type         = 'polhemus';
0408 chanformat(1).typestring   = 'Polhemus native .elp file';
0409 chanformat(1).description  = [ 'Polhemus native coordinate file containing scanned electrode positions. ' ...
0410                                'User must select the direction ' ...
0411                                'for the nose after importing the data file.' ];
0412 chanformat(1).importformat = 'readelp() function';
0413 % ---------------------------------------------------------------------------------------------------
0414 chanformat(2).type         = 'besa';
0415 chanformat(2).typestring   = 'BESA spherical .elp file';
0416 chanformat(2).description  = [ 'BESA spherical coordinate file. Note that BESA spherical coordinates ' ...
0417                                'are different from Matlab spherical coordinates' ];
0418 chanformat(2).skipline     = -1;
0419 chanformat(2).importformat = { 'type' 'labels' 'sph_theta_besa' 'sph_phi_besa' 'sph_radius' };
0420 % ---------------------------------------------------------------------------------------------------
0421 chanformat(3).type         = 'xyz';
0422 chanformat(3).typestring   = 'Matlab .xyz file';
0423 chanformat(3).description  = [ 'Standard 3-D cartesian coordinate files with electrode labels in ' ...
0424                                'the first column and X, Y, and Z coordinates in columns 2, 3, and 4' ];
0425 chanformat(3).importformat = { 'channum' '-Y' 'X' 'Z' 'labels'};
0426 % ---------------------------------------------------------------------------------------------------
0427 chanformat(4).type         = 'sfp';
0428 chanformat(4).typestring   = 'BESA or EGI 3-D cartesian .sfp file';
0429 chanformat(4).description  = [ 'Standard BESA 3-D cartesian coordinate files with electrode labels in ' ...
0430                                'the first column and X, Y, and Z coordinates in columns 2, 3, and 4.' ...
0431                                'Coordinates are re-oriented to fit the EEGLAB standard of having the ' ...
0432                                'nose along the +X axis.' ];
0433 chanformat(4).importformat = { 'labels' '-Y' 'X' 'Z' };
0434 chanformat(4).skipline     = -1;
0435 % ---------------------------------------------------------------------------------------------------
0436 chanformat(5).type         = 'loc';
0437 chanformat(5).typestring   = 'EEGLAB polar .loc file';
0438 chanformat(5).description  = [ 'EEGLAB polar .loc file' ];
0439 chanformat(5).importformat = { 'channum' 'theta' 'radius' 'labels' };
0440 % ---------------------------------------------------------------------------------------------------
0441 chanformat(6).type         = 'sph';
0442 chanformat(6).typestring   = 'Matlab .sph spherical file';
0443 chanformat(6).description  = [ 'Standard 3-D spherical coordinate files in Matlab format' ];
0444 chanformat(6).importformat = { 'channum' 'sph_theta' 'sph_phi' 'labels' };
0445 % ---------------------------------------------------------------------------------------------------
0446 chanformat(7).type         = 'asc';
0447 chanformat(7).typestring   = 'Neuroscan polar .asc file';
0448 chanformat(7).description  = [ 'Neuroscan polar .asc file, automatically recentered to fit EEGLAB standard' ...
0449                                'of having ''Cz'' at (0,0).' ];
0450 chanformat(7).importformat = 'readneurolocs';
0451 % ---------------------------------------------------------------------------------------------------
0452 chanformat(8).type         = 'dat';
0453 chanformat(8).typestring   = 'Neuroscan 3-D .dat file';
0454 chanformat(8).description  = [ 'Neuroscan 3-D cartesian .dat file. Coordinates are re-oriented to fit ' ...
0455                                'the EEGLAB standard of having the nose along the +X axis.' ];
0456 chanformat(8).importformat = 'readneurolocs';
0457 % ---------------------------------------------------------------------------------------------------
0458 chanformat(9).type         = 'elc';
0459 chanformat(9).typestring   = 'ASA .elc 3-D file';
0460 chanformat(9).description  = [ 'ASA .elc 3-D coordinate file containing scanned electrode positions. ' ...
0461                                'User must select the direction ' ...
0462                                'for the nose after importing the data file.' ];
0463 chanformat(9).importformat = 'readeetraklocs';
0464 % ---------------------------------------------------------------------------------------------------
0465 chanformat(10).type         = 'chanedit';
0466 chanformat(10).typestring   = 'EEGLAB complete 3-D file';
0467 chanformat(10).description  = [ 'EEGLAB file containing polar, cartesian 3-D, and spherical 3-D ' ...
0468                                'electrode locations.' ];
0469 chanformat(10).importformat = { 'channum' 'labels'  'theta' 'radius' 'X' 'Y' 'Z' 'sph_theta' 'sph_phi' ...
0470                                'sph_radius' };
0471 chanformat(10).skipline     = 1;
0472 % ---------------------------------------------------------------------------------------------------
0473 chanformat(11).type         = 'custom';
0474 chanformat(11).typestring   = 'Custom file format';
0475 chanformat(11).description  = 'Custom ASCII file format where user can define content for each file columns.';
0476 chanformat(11).importformat = '';
0477 % ---------------------------------------------------------------------------------------------------
0478 % ----- ADD MORE FORMATS HERE -----------------------------------------------------------------------
0479 % ---------------------------------------------------------------------------------------------------
0480 
0481 listcolformat = { 'labels' 'channum' 'theta' 'radius' 'sph_theta' 'sph_phi' ...
0482       'sph_radius' 'sph_theta_besa' 'sph_phi_besa' 'gain' 'calib' 'type' ...
0483       'X' 'Y' 'Z' '-X' '-Y' '-Z' 'custom1' 'custom2' 'custom3' 'custom4' 'ignore' 'not def' };
0484 
0485 % ----------------------------------
0486 % special mode for getting the info
0487 % ----------------------------------
0488 if isstr(filename) & strcmp(filename, 'getinfos')
0489    eloc = chanformat;
0490    labels = listcolformat;
0491    return;
0492 end;
0493 
0494 g = finputcheck( varargin, ...
0495    { 'filetype'       'string'  {}                 '';
0496      'importmode'  'string'  { 'eeglab' 'native' } 'eeglab';
0497      'defaultelp'  'string'  { 'besa'   'polhemus' } 'polhemus';
0498      'skiplines'   'integer' [0 Inf]             [];
0499      'elecind'     'integer' [1 Inf]            [];
0500      'format'       'cell'     []                    {} }, 'readlocs');
0501 if isstr(g), error(g); end;  
0502 
0503 if isstr(filename)
0504    
0505    % format auto detection
0506     % --------------------
0507    if strcmpi(g.filetype, 'autodetect'), g.filetype = ''; end;
0508    g.filetype = strtok(g.filetype);
0509    periods = find(filename == '.');
0510    fileextension = filename(periods(end)+1:end);
0511    g.filetype = lower(g.filetype);
0512    if isempty(g.filetype)
0513        switch lower(fileextension),
0514         case {'loc' 'locs' }, g.filetype = 'loc';
0515         case 'xyz', g.filetype = 'xyz'; 
0516           fprintf( [ 'WARNING: Matlab Cartesian coord. file extension (".xyz") detected.\n' ... 
0517                   'If importing EGI Cartesian coords, force type "sfp" instead.\n'] );
0518         case 'sph', g.filetype = 'sph';
0519         case 'ced', g.filetype = 'chanedit';
0520         case 'elp', g.filetype = g.defaultelp;
0521         case 'asc', g.filetype = 'asc';
0522         case 'dat', g.filetype = 'dat';
0523         case 'elc', g.filetype = 'elc';
0524         case 'eps', g.filetype = 'besa';
0525         case 'sfp', g.filetype = 'sfp';
0526         otherwise, g.filetype =  ''; 
0527        end;
0528        fprintf('readlocs(): ''%s'' format assumed from file extension\n', g.filetype); 
0529    else 
0530        if strcmpi(g.filetype, 'locs'),  g.filetype = 'loc'; end
0531        if strcmpi(g.filetype, 'eloc'),  g.filetype = 'loc'; end
0532    end;
0533    
0534    % assign format from filetype
0535    % ---------------------------
0536    if ~isempty(g.filetype) & ~strcmpi(g.filetype, 'custom') ...
0537            & ~strcmpi(g.filetype, 'asc') & ~strcmpi(g.filetype, 'elc') & ~strcmpi(g.filetype, 'dat')
0538       indexformat = strmatch(lower(g.filetype), { chanformat.type }, 'exact');
0539       g.format = chanformat(indexformat).importformat;
0540       if isempty(g.skiplines)
0541          g.skiplines = chanformat(indexformat).skipline;
0542       end;
0543       if isempty(g.filetype) 
0544          error( ['readlocs() error: The filetype cannot be detected from the \n' ...
0545                  '                  file extension, and custom format not specified']);
0546       end;
0547    end;
0548    
0549    % import file
0550    % -----------
0551    if strcmp(g.filetype, 'asc') | strcmp(g.filetype, 'dat')
0552        eloc = readneurolocs( filename );
0553        eloc = rmfield(eloc, 'sph_theta'); % for the conversion below
0554        eloc = rmfield(eloc, 'sph_theta_besa'); % for the conversion below
0555    elseif strcmp(g.filetype, 'elc')
0556        eloc = readeetraklocs( filename );
0557        %eloc = read_asa_elc( filename ); % from fieldtrip
0558        %eloc = struct('labels', eloc.label, 'X', mattocell(eloc.pnt(:,1)'), 'Y', ...
0559        %                        mattocell(eloc.pnt(:,2)'), 'Z', mattocell(eloc.pnt(:,3)'));
0560        eloc = convertlocs(eloc, 'cart2all');
0561        eloc = rmfield(eloc, 'sph_theta'); % for the conversion below
0562        eloc = rmfield(eloc, 'sph_theta_besa'); % for the conversion below
0563    elseif strcmp(lower(g.filetype(1:end-1)), 'polhemus') | ...
0564            strcmp(g.filetype, 'polhemus')
0565        try, 
0566            [eloc labels X Y Z]= readelp( filename );
0567            if strcmp(g.filetype, 'polhemusy')
0568                tmp = X; X = Y; Y = tmp;
0569            end;
0570            for index = 1:length( eloc )
0571                eloc(index).X = X(index);
0572                eloc(index).Y = Y(index);    
0573                eloc(index).Z = Z(index);    
0574            end;
0575        catch, 
0576            disp('readlocs(): Could not read Polhemus coords. Trying to read BESA .elp file.');
0577            [eloc, labels, theta, radius, indices] = readlocs( filename, 'defaultelp', 'besa', varargin{:} );
0578        end;
0579    else      
0580        % importing file
0581        % --------------
0582        if isempty(g.skiplines), g.skiplines = 0; end;
0583        array = load_file_or_array( filename, max(g.skiplines,0));
0584        if size(array,2) < length(g.format)
0585            fprintf(['readlocs() warning: Fewer columns in the input than expected.\n' ...
0586                     '                    See >> help readlocs\n']);
0587        elseif size(array,2) > length(g.format)
0588            fprintf(['readlocs() warning: More columns in the input than expected.\n' ...
0589                     '                    See >> help readlocs\n']);
0590        end;
0591        
0592        % removing lines BESA
0593        % -------------------
0594        if g.skiplines == -1
0595            if isempty(array{1,2})
0596                disp('BESA header detected, skipping three lines...');
0597                array = load_file_or_array( filename, -2);
0598            end;
0599        end;
0600        
0601        % removing comments and empty lines
0602        % ---------------------------------
0603        indexbeg = 1;
0604        while isempty(array{indexbeg,1}) | ...
0605                (isstr(array{indexbeg,1}) & array{indexbeg,1}(1) == '%' )
0606            indexbeg = indexbeg+1;
0607        end;
0608        array = array(indexbeg:end,:);
0609        
0610        % converting file
0611        % ---------------
0612        for indexcol = 1:min(size(array,2), length(g.format))
0613            [str mult] = checkformat(g.format{indexcol});
0614            for indexrow = 1:size( array, 1)
0615                if mult ~= 1
0616                    eval ( [ 'eloc(indexrow).'  str '= -array{indexrow, indexcol};' ]);
0617                else
0618                    eval ( [ 'eloc(indexrow).'  str '= array{indexrow, indexcol};' ]);
0619                end;
0620            end;
0621        end;
0622    end;
0623    
0624    % handling BESA coordinates
0625    % -------------------------
0626    if isfield(eloc, 'sph_theta_besa')
0627        if isnumeric(eloc(1).type)
0628            disp('BESA format detected ( Theta | Phi )');
0629            for index = 1:length(eloc)
0630                eloc(index).sph_phi_besa   = eloc(index).labels;
0631                eloc(index).sph_theta_besa = eloc(index).type;
0632                eloc(index).labels         = '';
0633                eloc(index).type           = '';
0634            end;
0635            eloc = rmfield(eloc, 'labels');
0636        elseif isnumeric(eloc(1).labels)
0637            disp('BESA format detected ( Elec | Theta | Phi )');
0638            for index = 1:length(eloc)
0639                eloc(index).sph_phi_besa   = eloc(index).sph_theta_besa;
0640                eloc(index).sph_theta_besa = eloc(index).labels;
0641                eloc(index).labels         = eloc(index).type;
0642                eloc(index).type           = '';
0643                eloc(index).radius         = 1;
0644            end;           
0645        else
0646            disp('BESA format detected ( Type | Elec | Theta | Phi | Radius )');           
0647        end;
0648        
0649        try
0650            eloc = convertlocs(eloc, 'sphbesa2all');
0651            eloc = convertlocs(eloc, 'topo2all'); % problem with some EGI files (not BESA files)
0652        catch, disp('Warning: coordinate conversion failed'); end;
0653        fprintf('Readlocs: BESA spherical coords. converted, now deleting BESA fields\n');   
0654        fprintf('          to avoid confusion (these fields can be exported, though)\n');   
0655        eloc = rmfield(eloc, 'sph_phi_besa');
0656        eloc = rmfield(eloc, 'sph_theta_besa');
0657 
0658        % converting XYZ coordinates to polar
0659        % -----------------------------------
0660    elseif isfield(eloc, 'sph_theta')
0661        try
0662            eloc = convertlocs(eloc, 'sph2all');  
0663        catch, disp('Warning: coordinate conversion failed'); end;
0664    elseif isfield(eloc, 'X')
0665        try
0666            eloc = convertlocs(eloc, 'cart2all');  
0667        catch, disp('Warning: coordinate conversion failed'); end;
0668    else 
0669        try
0670            eloc = convertlocs(eloc, 'topo2all');  
0671        catch, disp('Warning: coordinate conversion failed'); end;
0672    end;
0673    
0674    % inserting labels if no labels
0675    % -----------------------------
0676    if ~isfield(eloc, 'labels')
0677        fprintf('readlocs(): Inserting electrode labels automatically.\n');
0678        for index = 1:length(eloc)
0679            eloc(index).labels = [ 'E' int2str(index) ];
0680        end;
0681    else 
0682        % remove trailing '.'
0683        for index = 1:length(eloc)
0684            if isstr(eloc(index).labels)
0685                tmpdots = find( eloc(index).labels == '.' );
0686                eloc(index).labels(tmpdots) = [];
0687            end;
0688        end;
0689    end;
0690    
0691    % resorting electrodes if number not-sorted
0692    % -----------------------------------------
0693    if isfield(eloc, 'channum')
0694        if ~isnumeric(eloc(1).channum)
0695            error('Channel numbers must be numeric');
0696        end;
0697        allchannum = [ eloc.channum ];
0698        if any( sort(allchannum) ~= allchannum )
0699            fprintf('readlocs(): Re-sorting channel numbers based on ''channum'' column indices\n');
0700            [tmp newindices] = sort(allchannum);
0701            eloc = eloc(newindices);
0702        end;
0703        eloc = rmfield(eloc, 'channum');      
0704    end;
0705 else
0706     if isstruct(filename)
0707         eloc = filename;
0708     else
0709         disp('readlocs(): input variable must be a string or a structure');
0710     end;        
0711 end;
0712 if ~isempty(g.elecind)
0713     eloc = eloc(g.elecind);
0714 end;
0715 if nargout > 2
0716     tmptheta          = { eloc.theta }; % check which channels have (polar) coordinates set
0717     indices           = find(~cellfun('isempty', tmptheta));
0718     indbad            = find(cellfun('isempty', tmptheta));
0719     tmptheta(indbad)  = { NaN };
0720     theta             = [ tmptheta{:} ];
0721 end;
0722 if nargout > 3
0723     tmprad            = { eloc.radius };
0724     tmprad(indbad)    = { NaN };
0725     radius            = [ tmprad{:} ];
0726 end;
0727 %tmpnum = find(~cellfun('isclass', { eloc.labels }, 'char'));
0728 %disp('Converting channel labels to string');
0729 for index = 1:length(eloc)
0730     if ~isstr(eloc(index).labels)
0731         eloc(index).labels = int2str(eloc(index).labels);
0732     end;
0733 end;
0734 labels = { eloc.labels };
0735 if isfield(eloc, 'ignore')
0736     eloc = rmfield(eloc, 'ignore');
0737 end;
0738 
0739 % process fiducials if any
0740 % ------------------------
0741 fidnames = { 'nz' 'lpa' 'rpa' };
0742 for index = 1:length(fidnames)
0743     ind = strmatch(fidnames{index}, lower(labels), 'exact');
0744     if ~isempty(ind), eloc(ind).type = 'FID'; end;
0745 end;
0746 
0747 return;
0748 
0749 % interpret the variable name
0750 % ---------------------------
0751 function array = load_file_or_array( varname, skiplines );
0752      if isempty(skiplines),
0753        skiplines = 0;
0754     end;
0755     if exist( varname ) == 2
0756         array = loadtxt(varname,'verbose','off','skipline',skiplines);
0757     else % variable in the global workspace
0758          % --------------------------
0759          try, array = evalin('base', varname);
0760          catch, error('readlocs(): cannot find the named file or variable, check syntax');
0761          end;
0762     end;     
0763 return;
0764 
0765 % check field format
0766 % ------------------
0767 function [str, mult] = checkformat(str)
0768     mult = 1;
0769     if strcmpi(str, 'labels'),         str = lower(str); return; end;
0770     if strcmpi(str, 'channum'),        str = lower(str); return; end;
0771     if strcmpi(str, 'theta'),          str = lower(str); return; end;
0772     if strcmpi(str, 'radius'),         str = lower(str); return; end;
0773     if strcmpi(str, 'ignore'),         str = lower(str); return; end;
0774     if strcmpi(str, 'sph_theta'),      str = lower(str); return; end;
0775     if strcmpi(str, 'sph_phi'),        str = lower(str); return; end;
0776     if strcmpi(str, 'sph_radius'),     str = lower(str); return; end;
0777     if strcmpi(str, 'sph_theta_besa'), str = lower(str); return; end;
0778     if strcmpi(str, 'sph_phi_besa'),   str = lower(str); return; end;
0779     if strcmpi(str, 'gain'),           str = lower(str); return; end;
0780     if strcmpi(str, 'calib'),          str = lower(str); return; end;
0781     if strcmpi(str, 'type') ,          str = lower(str); return; end;
0782     if strcmpi(str, 'X'),              str = upper(str); return; end;
0783     if strcmpi(str, 'Y'),              str = upper(str); return; end;
0784     if strcmpi(str, 'Z'),              str = upper(str); return; end;
0785     if strcmpi(str, '-X'),             str = upper(str(2:end)); mult = -1; return; end;
0786     if strcmpi(str, '-Y'),             str = upper(str(2:end)); mult = -1; return; end;
0787     if strcmpi(str, '-Z'),             str = upper(str(2:end)); mult = -1; return; end;
0788     if strcmpi(str, 'custom1'), return; end;
0789     if strcmpi(str, 'custom2'), return; end;
0790     if strcmpi(str, 'custom3'), return; end;
0791     if strcmpi(str, 'custom4'), return; end;
0792     error(['readlocs(): undefined field ''' str '''']);
0793

Generated on Sun 04-Apr-2010 04:01:39 by m2html © 2003