📄 subsref.m
字号:
function outvar = subsref(htio, S)
% transio::subsref - overloaded method
%
% transio(I) - values at position(s) I
% transio(XI, YI) - values at position(s) XI, YI
% ...
% Version: v0.7b
% Build: 7082923
% Date: Aug-29 2007, 11:25 PM CEST
% Author: Jochen Weber, Brain Innovation, B.V., Maastricht, NL
% URL/Info: http://wiki.brainvoyager.com/BVQXtools
% argument check
if nargin < 2
error( ...
'transio:BadSubsRef', ...
'No S subsref struct given.' ...
);
end
% get datatype and type size for access functions
csn = ['*' htio.DataType];
csz = htio.TypeSize;
siz = htio.DataDims;
% parse S
try
% use external function to efficiently get indices
[ots, idx, ridx, cidx, lastcol] = ioidx(S, siz);
pots = prod(ots);
if length(ots) > length(siz)
cpr = [1, cumprod(ots)]';
else
cpr = [1, cumprod(siz)]';
end
lsz = length(idx);
lsx = lsz + 1;
if length(cpr) > lsx
cpr = cpr(1:lsx);
end
catch
error( ...
'transio:BadSubsRef', ...
'Invalid S subsref struct given: ''%s''.', ...
lasterr ...
);
end
% initialize output to class
outvar = eval([csn(2:end) '(0)']);
% return empty if nothing is to be read
if pots < 1
outvar(1) = [];
outvar = reshape(outvar, ots);
return;
end
% open file and check
try
if htio.LittleND
fid = fopen(htio.FileName, 'rb', 'ieee-le');
else
fid = fopen(htio.FileName, 'rb', 'ieee-be');
end
catch
fid = 0;
end
if fid < 1
error( ...
'transio:FileNotOpen', ...
'Error opening file: ''%s''.', ...
htio.FileName ...
);
end
% get offset within file
ofs = htio.IOOffset;
% take specific care of one length arguments
if lsz == 1
% treat singular-index input
idx = idx{1};
% character index
if ischar(idx)
% go to position
try
fseek(fid, ofs, -1);
outvar = fread(fid, [pots, 1], csn);
catch
fclose(fid);
error( ...
'transio:FileReadError', ...
'Error reading array(:) from file.' ...
);
end
fclose(fid);
return;
end
% if contiguous
if length(cidx{1}) < 3
% try read
try
fseek(fid, ofs + csz * (idx(1) - 1), -1);
outvar = reshape(fread(fid, [pots, 1], csn), ots);
catch
fclose(fid);
error( ...
'transio:FileReadError', ...
'Error reading array part from file.' ...
);
end
% otherwise
else
% initialize output
outvar(pots) = outvar(1);
outvar = reshape(outvar, ots);
% get cidx for fast access
cidx = cidx{1};
% then ...
try
% read as long as breaks are found
dsz = cidx(1);
for bc = 1:(length(cidx) - 1)
% get position of break
dsz2 = cidx(bc + 1);
% go to position in file
fseek(fid, ofs + csz * (idx(dsz) - 1), -1);
% read as much as needed
outvar(dsz:(dsz2 - 1)) = fread(fid, [dsz2 - dsz, 1], csn);
% and copy old break to new start
dsz = dsz2;
end
catch
error( ...
'transio:FileReadError', ...
'Error reading array part from file.' ...
);
end
end
% close file
fclose(fid);
% reorder indices if needed
if ~ischar(ridx{1})
outvar = reshape(outvar(ridx{1}), ots);
end
% return now
return;
% all are :
elseif lastcol == lsz
% go to first index and read entire array
try
fseek(fid, ofs, -1);
outvar = reshape(fread(fid, [pots, 1], csn), ots);
catch
fclose(fid);
error( ...
'transio:FileReadError', ...
'Error reading array(:,...,:) from file.' ...
);
end
% close file and keep track of it!
fclose(fid);
fid = 0;
% all but last are colon and last is contiguous
elseif lastcol == (lsz - 1) && ...
length(cidx{end}) < 3
% go to first index and read entire array
try
fseek(fid, ofs + csz * (idx{end}(1) - 1) * cpr(end - 1), -1);
outvar = reshape(fread(fid, [pots, 1], csn), ots);
catch
fclose(fid);
error( ...
'transio:FileReadError', ...
'Error reading array(:,...,I) from file.' ...
);
end
% close file and keep track of it!
fclose(fid);
fid = 0;
end
% reordering indices
rS.type = '()';
rS.subs = cell(1, lsz);
userS = false;
for bc = 1:lsz
rS.subs{bc} = ridx{bc};
if ~ischar(ridx{bc})
userS = true;
end
end
% something has been read already
if fid < 1
% apply reordering
if userS
outvar = reshape(subsref(outvar, rS), ots);
end
% return now
return;
end
% we have true multiple indexing, so initialize output now at the latest
outvar(pots) = outvar(1);
outvar = reshape(outvar, ots);
% rebuilt S
rds = ots;
ofc = ones(1, lsx);
otc = ones(1, lsx);
otf = ones(1, lsx);
S = struct;
S.type = '()';
S.subs = {':'};
rcol = lastcol + 1;
for cc = 1:lsz
if cc < rcol
S.subs{cc} = ':';
else
S.subs{cc} = 1;
ofc(cc) = idx{cc}(1);
% set final block counter
if length(cidx{cc}) > 1
otf(cc) = length(cidx{cc}) - 1;
else
otf(cc) = length(idx{cc});
end
rds(cc) = 1;
end
end
% read specific parts
cidx = cidx{rcol};
cpsiz = cpr(rcol);
while otc(end) < 2
% find position
rpos = ofs + csz * (ofc - 1) * cpr;
% which indices to read next
rstr = cidx(otc(rcol)):(cidx(otc(rcol)+1)-1);
S.subs{rcol} = rstr;
% number of indices
rsiz = length(rstr);
% set into reshape array
rds(rcol) = rsiz;
% calculate number of elements
rdp = cpsiz * rsiz;
% try to read and directly store in outvar
try
fseek(fid, rpos, -1);
subsasgn(outvar, S, reshape(fread(fid, [rdp, 1], csn), rds));
catch
fclose(fid);
error( ...
'transio:FileReadError', ...
'Error reading array part from file.' ...
);
end
% start with rcol
cc = rcol;
% and go on until last column reaches
while cc <= lsx
% increase block count
otc(cc) = otc(cc) + 1;
% more blocks to come for this dim?
if otc(cc) <= otf(cc)
% increase non-contiguous counter only for later dims
if cc > rcol
S.subs{cc} = S.subs{cc} + 1;
end
% reset ofc
if cc == rcol
ofc(cc) = idx{cc}(cidx(otc(cc)));
else
ofc(cc) = idx{cc}(otc(cc));
end
% go on ...
break;
% last column (termination criterion)
elseif cc > lsz
% means: leave reading loop!
break;
end
% set block counter for cc to 1
otc(cc) = 1;
% and also set subs structure
S.subs{cc} = 1;
% and ofc
ofc(cc) = idx{cc}(1);
% then increase column counter
cc = cc + 1;
end
end
% close file !!
fclose(fid);
% reorder indices for rcol ?
if userS
outvar = reshape(subsref(outvar, rS), ots);
end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -