Home > vbmeg > external > mne > fiff_read_tag.m

fiff_read_tag

PURPOSE ^

SYNOPSIS ^

function [tag] = fiff_read_tag(fid,pos)

DESCRIPTION ^

 [tag] = fiff_read_tag(fid,pos)

 Read one tag from a fif file.
 if pos is not provided, reading starts from the current file position

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SOURCE CODE ^

0001 function [tag] = fiff_read_tag(fid,pos)
0002 %
0003 % [tag] = fiff_read_tag(fid,pos)
0004 %
0005 % Read one tag from a fif file.
0006 % if pos is not provided, reading starts from the current file position
0007 %
0008 
0009 %
0010 %   Author : Matti Hamalainen, MGH Martinos Center
0011 %   License : BSD 3-clause
0012 %
0013 %
0014 %   Revision 1.16  2008/11/17 15:07:00  msh
0015 %   Added reading of short, unsigned short, and unsigned int data
0016 %
0017 %   Revision 1.15  2008/05/07 10:39:13  msh
0018 %   Added FIFFT_JULIAN
0019 %
0020 %   Revision 1.14  2008/03/25 18:13:29  msh
0021 %   Added reading of sparse matrices
0022 %
0023 %   Revision 1.13  2006/09/24 18:52:43  msh
0024 %   Added FIFFV_REF_MEG_CH to fiff_define_constants.
0025 %   Added coord_frame field to dig point structure.
0026 %
0027 %   Revision 1.12  2006/09/23 13:31:55  msh
0028 %   Added reading of complex and double complex arrays and matrices
0029 %
0030 %   Revision 1.11  2006/05/03 19:03:19  msh
0031 %   Eliminated the use of cast function for Matlab 6.5 compatibility
0032 %
0033 %   Revision 1.10  2006/05/03 18:53:04  msh
0034 %   Approaching Matlab 6.5 backward compatibility
0035 %
0036 %   Revision 1.9  2006/04/26 19:50:58  msh
0037 %   Added fiff_read_mri
0038 %
0039 %   Revision 1.8  2006/04/23 15:29:40  msh
0040 %   Added MGH to the copyright
0041 %
0042 %   Revision 1.7  2006/04/17 11:52:15  msh
0043 %   Added coil definition stuff
0044 %
0045 %   Revision 1.6  2006/04/15 12:21:00  msh
0046 %   Several small improvements
0047 %
0048 %   Revision 1.5  2006/04/13 21:20:06  msh
0049 %   Added new routines for the channel information transformation.
0050 %
0051 %   Revision 1.4  2006/04/13 17:53:31  msh
0052 %   Added coordinate frame to the channel info structure
0053 %
0054 %   Revision 1.3  2006/04/13 17:49:12  msh
0055 %   Added some more comments
0056 %
0057 %   Revision 1.2  2006/04/13 17:47:50  msh
0058 %   Make coil coordinate transformation or EEG electrode location out of the channel  info.
0059 %
0060 %   Revision 1.1  2006/04/10 23:26:54  msh
0061 %   Added fiff reading routines
0062 %
0063 %
0064 global FIFF;
0065 if isempty(FIFF)
0066     FIFF = fiff_define_constants();
0067 end
0068 
0069 me='MNE:fiff_read_tag';
0070 
0071 if nargin == 2
0072     fseek(fid,pos,'bof');
0073 elseif nargin ~= 1
0074     error(me,'Incorrect number of arguments');
0075 end
0076 
0077 tag.kind = fread(fid,1,'int32');
0078 tag.type = fread(fid,1,'uint32');
0079 tag.size = fread(fid,1,'int32');
0080 tag.next = fread(fid,1,'int32');
0081 %
0082 %   The magic hexadecimal values
0083 %
0084 is_matrix           = 4294901760; % ffff0000
0085 matrix_coding_dense = 16384;      % 4000
0086 matrix_coding_CCS   = 16400;      % 4010
0087 matrix_coding_RCS   = 16416;      % 4020
0088 data_type           = 65535;      % ffff
0089 %
0090 if tag.size > 0
0091     matrix_coding = bitand(is_matrix,tag.type);
0092     if matrix_coding ~= 0
0093         matrix_coding = bitshift(matrix_coding,-16);
0094         %
0095         %   Matrices
0096         %
0097         if matrix_coding == matrix_coding_dense
0098             %
0099             % Find dimensions and return to the beginning of tag data
0100             %
0101             pos = ftell(fid);
0102             fseek(fid,tag.size-4,'cof');
0103             ndim = fread(fid,1,'int32');
0104             fseek(fid,-(ndim+1)*4,'cof');
0105             dims = fread(fid,ndim,'int32');
0106             %
0107             % Back to where the data start
0108             %
0109             fseek(fid,pos,'bof');
0110             
0111             matrix_type = bitand(data_type,tag.type);
0112             
0113             if ndim == 2
0114                 switch matrix_type
0115                     case FIFF.FIFFT_INT
0116                         idata = fread(fid,dims(1)*dims(2),'int32=>int32');
0117                         tag.data = reshape(idata,dims(1),dims(2))';
0118                     case FIFF.FIFFT_JULIAN
0119                         idata = fread(fid,dims(1)*dims(2),'int32=>int32');
0120                         tag.data = reshape(idata,dims(1),dims(2))';
0121                     case FIFF.FIFFT_FLOAT
0122                         fdata = fread(fid,dims(1)*dims(2),'single=>double');
0123                         tag.data = reshape(fdata,dims(1),dims(2))';
0124                     case FIFF.FIFFT_DOUBLE
0125                         ddata = fread(fid,dims(1)*dims(2),'double=>double');
0126                         tag.data = reshape(ddata,dims(1),dims(2))';
0127                     case FIFF.FIFFT_COMPLEX_FLOAT
0128                         fdata = fread(fid,2*dims(1)*dims(2),'single=>double');
0129                         nel = length(fdata);
0130                         fdata = complex(fdata(1:2:nel),fdata(2:2:nel));
0131                         %
0132                         %   Note: we need the non-conjugate transpose here
0133                         %
0134                         tag.data = transpose(reshape(fdata,dims(1),dims(2)));
0135                     case FIFF.FIFFT_COMPLEX_DOUBLE
0136                         ddata = fread(fid,2*dims(1)*dims(2),'double=>double');
0137                         nel = length(ddata);
0138                         ddata = complex(ddata(1:2:nel),ddata(2:2:nel));
0139                         %
0140                         %   Note: we need the non-conjugate transpose here
0141                         %
0142                         tag.data = transpose(reshape(ddata,dims(1),dims(2)));
0143                     otherwise
0144                         error(me,'Cannot handle a 2D matrix of type %d yet',matrix_type)
0145                 end
0146             elseif ndim == 3
0147                 switch matrix_type
0148                     case FIFF.FIFFT_INT
0149                         idata = fread(fid,dims(1)*dims(2)*dims(3),'int32=>int32');
0150                         tag.data = reshape(idata,dims(1),dims(2),dims(3));
0151                     case FIFF.FIFFT_JULIAN
0152                         idata = fread(fid,dims(1)*dims(2)*dims(3),'int32=>int32');
0153                         tag.data = reshape(idata,dims(1),dims(2),dims(3));
0154                     case FIFF.FIFFT_FLOAT
0155                         fdata = fread(fid,dims(1)*dims(2)*dims(3),'single=>double');
0156                         tag.data = reshape(fdata,dims(1),dims(2),dims(3));
0157                     case FIFF.FIFFT_DOUBLE
0158                         ddata = fread(fid,dims(1)*dims(2)*dims(3),'double=>double');
0159                         tag.data = reshape(ddata,dims(1),dims(2),dims(3));
0160                     case FIFF.FIFFT_COMPLEX_FLOAT
0161                         fdata = fread(fid,2*dims(1)*dims(2)*dims(3),'single=>double');
0162                         nel = length(fdata);
0163                         fdata = complex(fdata(1:2:nel),fdata(2:2:nel));
0164                         tag.data = reshape(fdata,dims(1),dims(2),dims(3));
0165                     case FIFF.FIFFT_COMPLEX_DOUBLE
0166                         ddata = fread(fid,2*dims(1)*dims(2)*dims(3),'double=>double');
0167                         nel = length(ddata);
0168                         ddata = complex(ddata(1:2:nel),ddata(2:2:nel));
0169                         tag.data = reshape(ddata,dims(1),dims(2),dims(3));
0170                     otherwise
0171                         error(me,'Cannot handle a 3D matrix of type %d yet',matrix_type)
0172                 end
0173                 %
0174                 %   Permute
0175                 %
0176                 tag.data = permute(tag.data,[ 3 2 1 ]);
0177             else
0178                 error(me, ...
0179                     'Only two and three dimensional matrices are supported at this time');
0180             end
0181         elseif (matrix_coding == matrix_coding_CCS || matrix_coding == matrix_coding_RCS)
0182             %
0183             % Find dimensions and return to the beginning of tag data
0184             %
0185             pos = ftell(fid);
0186             fseek(fid,tag.size-4,'cof');
0187             ndim = fread(fid,1,'int32');
0188             fseek(fid,-(ndim+2)*4,'cof');
0189             dims = fread(fid,ndim+1,'int32');
0190             if ndim ~= 2
0191                 error(me,'Only two-dimensional matrices are supported at this time');
0192             end
0193             %
0194             % Back to where the data start
0195             %
0196             fseek(fid,pos,'bof');
0197             nnz   = dims(1);
0198             nrow  = dims(2);
0199             ncol  = dims(3);
0200             sparse_data = zeros(nnz,3);
0201             sparse_data(:,3) = fread(fid,nnz,'single=>double');
0202             if (matrix_coding == matrix_coding_CCS)
0203                 %
0204                 %    CCS
0205                 %
0206                 sparse_data(:,1)  = fread(fid,nnz,'int32=>double') + 1;
0207                 ptrs  = fread(fid,ncol+1,'int32=>double') + 1;
0208                 p = 1;
0209                 for j = 1:ncol
0210                     while p < ptrs(j+1)
0211                         sparse_data(p,2) = j;
0212                         p = p + 1;
0213                     end
0214                 end
0215             else
0216                 %
0217                 %    RCS
0218                 %
0219                 sparse_data(:,2)  = fread(fid,nnz,'int32=>double') + 1;
0220                 ptrs  = fread(fid,nrow+1,'int32=>double') + 1;
0221                 p = 1;
0222                 for j = 1:nrow
0223                     while p < ptrs(j+1)
0224                         sparse_data(p,1) = j;
0225                         p = p + 1;
0226                     end
0227                 end
0228             end
0229             tag.data = spconvert(sparse_data);
0230             tag.data(nrow,ncol) = 0.0;
0231         else
0232             error(me,'Cannot handle other than dense or sparse matrices yet')
0233         end
0234     else
0235         %
0236         %   All other data types
0237         %
0238         switch tag.type
0239             %
0240             %   Simple types
0241             %
0242             case FIFF.FIFFT_BYTE
0243                 tag.data = fread(fid,tag.size,'uint8=>uint8');
0244             case FIFF.FIFFT_SHORT
0245                 tag.data = fread(fid,tag.size/2,'int16=>int16');
0246             case FIFF.FIFFT_INT
0247                 tag.data = fread(fid,tag.size/4,'int32=>int32');
0248             case FIFF.FIFFT_USHORT
0249                 tag.data = fread(fid,tag.size/2,'uint16=>uint16');
0250             case FIFF.FIFFT_UINT
0251                 tag.data = fread(fid,tag.size/4,'uint32=>uint32');
0252             case FIFF.FIFFT_FLOAT
0253                 tag.data = fread(fid,tag.size/4,'single=>double');
0254             case FIFF.FIFFT_DOUBLE
0255                 tag.data = fread(fid,tag.size/8,'double');
0256             case FIFF.FIFFT_STRING
0257                 tag.data = fread(fid,tag.size,'uint8=>char')';
0258             case FIFF.FIFFT_DAU_PACK16
0259                 tag.data = fread(fid,tag.size/2,'int16=>int16');
0260             case FIFF.FIFFT_COMPLEX_FLOAT
0261                 tag.data = fread(fid,tag.size/4,'single=>double');
0262                 nel = length(tag.data);
0263                 tag.data = complex(tag.data(1:2:nel),tag.data(2:2:nel));
0264             case FIFF.FIFFT_COMPLEX_DOUBLE
0265                 tag.data = fread(fid,tag.size/8,'double');
0266                 nel = length(tag.data);
0267                 tag.data = complex(tag.data(1:2:nel),tag.data(2:2:nel));
0268                 %
0269                 %   Structures
0270                 %
0271             case FIFF.FIFFT_ID_STRUCT
0272                 tag.data.version = fread(fid,1,'int32=>int32');
0273                 tag.data.machid  = fread(fid,2,'int32=>int32');
0274                 tag.data.secs    = fread(fid,1,'int32=>int32');
0275                 tag.data.usecs   = fread(fid,1,'int32=>int32');
0276             case FIFF.FIFFT_DIG_POINT_STRUCT
0277                 tag.data.kind    = fread(fid,1,'int32=>int32');
0278                 tag.data.ident   = fread(fid,1,'int32=>int32');
0279                 tag.data.r       = fread(fid,3,'single=>single');
0280                 tag.data.coord_frame = 0;
0281             case FIFF.FIFFT_COORD_TRANS_STRUCT
0282                 tag.data.from = fread(fid,1,'int32=>int32');
0283                 tag.data.to   = fread(fid,1,'int32=>int32');
0284                 rot  = fread(fid,9,'single=>double');
0285                 rot = reshape(rot,3,3)';
0286                 move = fread(fid,3,'single=>double');
0287                 tag.data.trans = [ rot move ; [ 0  0 0 1 ]];
0288                 %
0289                 % Skip over the inverse transformation
0290                 % It is easier to just use inverse of trans in Matlab
0291                 %
0292                 fseek(fid,12*4,'cof');
0293             case FIFF.FIFFT_CH_INFO_STRUCT
0294                 tag.data.scanno    = fread(fid,1,'int32=>int32');
0295                 tag.data.logno     = fread(fid,1,'int32=>int32');
0296                 tag.data.kind      = fread(fid,1,'int32=>int32');
0297                 tag.data.range     = fread(fid,1,'single=>double');
0298                 tag.data.cal       = fread(fid,1,'single=>double');
0299                 tag.data.coil_type = fread(fid,1,'int32=>int32');
0300                 %
0301                 %   Read the coil coordinate system definition
0302                 %
0303                 tag.data.loc        = fread(fid,12,'single=>double');
0304                 tag.data.coil_trans  = [];
0305                 tag.data.eeg_loc     = [];
0306                 tag.data.coord_frame = FIFF.FIFFV_COORD_UNKNOWN;
0307                 %
0308                 %   Convert loc into a more useful format
0309                 %
0310                 loc = tag.data.loc;
0311                 if tag.data.kind == FIFF.FIFFV_MEG_CH || tag.data.kind == FIFF.FIFFV_REF_MEG_CH
0312                     tag.data.coil_trans  = [ [ loc(4:6) loc(7:9) loc(10:12) loc(1:3) ] ; [ 0 0 0 1 ] ];
0313                     tag.data.coord_frame = FIFF.FIFFV_COORD_DEVICE;
0314                 elseif tag.data.kind == FIFF.FIFFV_EEG_CH
0315                     if norm(loc(4:6)) > 0
0316                         tag.data.eeg_loc     = [ loc(1:3) loc(4:6) ];
0317                     else
0318                         tag.data.eeg_loc = [ loc(1:3) ];
0319                     end
0320                     tag.data.coord_frame = FIFF.FIFFV_COORD_HEAD;
0321                 end
0322                 %
0323                 %   Unit and exponent
0324                 %
0325                 tag.data.unit     = fread(fid,1,'int32=>int32');
0326                 tag.data.unit_mul = fread(fid,1,'int32=>int32');
0327                 %
0328                 %   Handle the channel name
0329                 %
0330                 ch_name   = fread(fid,16,'uint8=>char')';
0331                 %
0332                 % Omit nulls
0333                 %
0334                 len = 16;
0335                 for k = 1:16
0336                     if ch_name(k) == 0
0337                         len = k-1;
0338                         break
0339                     end
0340                 end
0341                 tag.data.ch_name = ch_name(1:len);
0342             case FIFF.FIFFT_OLD_PACK
0343                 offset   = fread(fid,1,'single=>double');
0344                 scale    = fread(fid,1,'single=>double');
0345                 tag.data = fread(fid,(tag.size-8)/2,'int16=>short');
0346                 tag.data = scale*single(tag.data) + offset;
0347             case FIFF.FIFFT_DIR_ENTRY_STRUCT
0348                 tag.data = struct('kind',{},'type',{},'size',{},'pos',{});
0349                 for k = 1:tag.size/16-1
0350                     kind = fread(fid,1,'int32');
0351                     type = fread(fid,1,'uint32');
0352                     tagsize = fread(fid,1,'int32');
0353                     pos  = fread(fid,1,'int32');
0354                     tag.data(k).kind = kind;
0355                     tag.data(k).type = type;
0356                     tag.data(k).size = tagsize;
0357                     tag.data(k).pos  = pos;
0358                 end
0359                 
0360             otherwise
0361                 error(me,'Unimplemented tag data type %d',tag.type);
0362                 
0363         end
0364     end
0365 end
0366 
0367 if tag.next ~= FIFF.FIFFV_NEXT_SEQ
0368     fseek(fid,tag.next,'bof');
0369 end
0370 
0371 return;
0372 
0373 end

Generated on Mon 22-May-2023 06:53:56 by m2html © 2005