⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 subsasgn.m

📁 toolbox of BVQX, This is the access between BV and matlab. It will help you to analysis data from BV
💻 M
字号:
function htio = subsasgn(htio, S, V)
% transio::subsasgn  - overloaded method
%
% transio(I) = V       - write values at position(s) I
% transio(XI, YI) = V  - write 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

% class check
if nargin > 2 && ...
    ~isa(htio, 'transio')
    try
        htio = builtin('subsasgn', htio, S, V);
    catch
        rethrow(lasterror);
    end
    return;
end

% argument check
if nargin < 3 || ...
   ~isstruct(S) || ...
   (~strcmpi(htio.DataType, class(V)) && ...
    ~isa(V, 'double'))
    error( ...
        'transio:BadSubsAsgn', ...
        'No or bad S struct, or no or bad V given.' ...
    );
end

% get and check sizes
csn = htio.DataType;
csz = htio.TypeSize;
siz = htio.DataDims;
Vsz = size(V);
pvs = prod(Vsz);

% parse S
try

    % use external function to efficiently get indices
    [its, idx, ridx, cidx, lastcol] = ioidx(S, siz);
    pits = prod(its);
    if length(its) > length(siz)
        cpr = [1, cumprod(its)]';
    else
        cpr = [1, cumprod(siz)]';
    end
    lsz = length(idx);
    lsx = lsz + 1;
    if length(cpr) > lsx
        cpr = cpr(1:lsx);
    end
    if numel(its) > numel(Vsz) && ...
        all(its(numel(Vsz)+1:end) == 1)
        Vsz = [Vsz, ones(1, numel(its) - numel(Vsz))];
    end
catch
    error( ...
        'transio:BadSubsAsgn', ...
        'Invalid S subsref struct given: ''%s''.', ...
        lasterr ...
    );
end

% check size(V) with its
if pvs ~= pits && ...
    pvs ~= 1
    error( ...
        'transio:BadSubsAsgn', ...
        'Invalid number of elements, must match S or be 1.' ...
    );

% only one value given but more needed
elseif pvs == 1 && ...
    pits > 1

    % make sure not to waste more space as needed
    if isa(V, 'double') && ...
       ~strcmpi(csn, 'double')
        try
            eval(['V=' csn '(V);']);
        catch
            error( ...
                'transio:ConversionFailed', ...
                'Error converting double to %s.', ...
                csn ...
            );
        end
    end

    % blow up to larger array for write operation
    V = repmat(V, its);

elseif length(Vsz) ~= length(its) || ...
    any(Vsz ~= its)
    warning( ...
        'transio:BadArgumentSize', ...
        'Possibly bad argument. Reshaping to good size...' ...
    );
    V = reshape(V, its);
end

% check if sizes match now!
if numel(V) ~= pits
    error( ...
        'transio:SizeMismatch', ...
        'Input value V and sizes in S mismatch.' ...
    );
end

% open file and check
try
    if htio.LittleND
        fid = fopen(htio.FileName, 'r+b', 'ieee-le');
    else
        fid = fopen(htio.FileName, 'r+b', 'ieee-be');
    end
catch
    fid = 0;
end
if fid < 1
    error( ...
        'transio:FileNotOpen', ...
        'Error opening file ''%s'' for writing.', ...
        htio.FileName ...
    );
end

% get offset into file
ofs = htio.IOOffset;

% check for reordering indices
rS.type = '()';
rS.subs = cell(1, lsz);
userS = false;
for bc = 1:lsz
    if ~ischar(ridx{bc})
        [sidx{1:2}] = sort(ridx{bc});
        userS = true;
    else
        sidx = {'', ':'};
    end
    rS.subs{bc} = sidx{2};
end

% do resorting
if userS
    V = reshape(subsref(V, rS), Vsz);
end

% take specific care of one length arguments
if lsz == 1

    % treat singular-index input
    idx = idx{1};

    % character indexing (all elements)
    if ischar(idx)

        % go to position
        try
            fseek(fid, ofs, -1);
            fwrite(fid, V, csn);
        catch
            fclose(fid);
            error( ...
                'transio:FileWriteError', ...
                'Error writing array to file.' ...
            );
        end
        fclose(fid);
        return;
    end

    % if contiguous
    if length(cidx{1}) < 3

        % go to first index and write array
        try
            fseek(fid, ofs + csz * (idx(1) - 1), -1);
            fwrite(fid, V, csn);
        catch
            fclose(fid);
            error( ...
                'transio:FileWriteError', ...
                'Error writing array part to file.' ...
            );
        end

    % otherwise
    else
        % 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);

                % write as much as needed
                fwrite(fid, V(dsz:(dsz2 - 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 and return
    fclose(fid);
    return;

% all are :
elseif lastcol == lsz

    % go to first index and read entire array
    try
        fseek(fid, ofs, -1);
        fwrite(fid, V, csn);
    catch
        fclose(fid);
        error( ...
            'transio:FileWriteError', ...
            'Error writing array to file.' ...
        );
    end

    % close file and return
    fclose(fid);
    return;

% 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);
        fwrite(fid, V, csn);
    catch
        fclose(fid);
        error( ...
            'transio:FileReadError', ...
            'Error reading array(:,...,I) from file.' ...
        );
    end

    % close file and return
    fclose(fid);
    return
end

% rebuilt S
rds = its;
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

% write specific parts
cidx = cidx{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;

    % try to write array elements
    try
        fseek(fid, rpos, -1);
        fwrite(fid, subsref(V, S), csn);
    catch
        fclose(fid);
        error( ...
            'transio:FileReadError', ...
            'Error writing array part to 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);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -