0001 function [tag] = fiff_read_tag(fid,pos)
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
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
0083
0084 is_matrix = 4294901760;
0085 matrix_coding_dense = 16384;
0086 matrix_coding_CCS = 16400;
0087 matrix_coding_RCS = 16416;
0088 data_type = 65535;
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
0096
0097 if matrix_coding == matrix_coding_dense
0098
0099
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
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
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
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
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
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
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
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
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
0237
0238 switch tag.type
0239
0240
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
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
0290
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
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
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
0324
0325 tag.data.unit = fread(fid,1,'int32=>int32');
0326 tag.data.unit_mul = fread(fid,1,'int32=>int32');
0327
0328
0329
0330 ch_name = fread(fid,16,'uint8=>char')';
0331
0332
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