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

📄 tffio.m

📁 toolbox of BVQX, This is the access between BV and matlab. It will help you to analysis data from BV
💻 M
📖 第 1 页 / 共 4 页
字号:
function [varargout] = tffio(varargin)
% tffio  - read/write binary file with TFF spec (and content)
%
% FORMAT:       tffcont = tffio(filename, tffspec [, options])
%          OR   tffio(wfilename, tffspec, tffcont [, options])
%
% Input fields:
%
%       filename    filename of binary file to read
%       tffspec     either filename or content or spec struct of TFF
%       options     optional arguments, one of
%                   'verbose', 'v' or '-v' (for verbose reading/writing)
%                   'force', 'f', '-f' (for returning partial content)
%
%       wfilename   filename of binary file to write
%       tffcont     file content (struct)
%
% Output fields:
%
%       tffcont     file contents struct (depending on TFF)
%
% See also tffdocu, tffparse

% Version:  v0.7a
% Build:    7080111
% Date:     Aug-01 2007, 11:54 AM CEST
% Author:   Jochen Weber, Brain Innovation, B.V., Maastricht, NL
% URL/Info: http://wiki.brainvoyager.com/BVQXtools

tffversion = 'v0.7a';

% argument check
if nargin < 2 || ...
    ~ischar(varargin{1}) || ...
    isempty(varargin{1}) || ...
    (~isstruct(varargin{2}) && ~ischar(varargin{2})) || ...
    isempty(varargin{2})
    error( ...
        'BVQXtools:BadArgument', ...
        'Bad or missing argument for tffio.' ...
    );
end
filename = varargin{1}(:)';
tffspec  = varargin{2}(:)';
tffcont  = [];

% default options
forcemode   = false;
verbosemode = false;
writemode   = false;

% tff content structure given
if nargin > 2 && ...
    isstruct(varargin{3}) && ...
   ~isempty(varargin{3})
    tffcont = varargin{3};
    writemode = true;
end

% check additional arguments
if nargin > 2
    for argc = 3:nargin

        % what is given
        argv = varargin{argc};

        % character argument
        if strcmpi(class(argv), 'char')

            % known argument
            switch lower(argv)

                % force mode
                case {'f', 'force', '-f'}
                    forcemode = true;

                % verbose mode
                case {'v', 'verbose', '-v'}
                    verbosemode = true;

            end

        % discard other arguments/options
        end
    end
end

% TFF is a valid SPEC struct
if isstruct(tffspec) && ...
   ~isempty(tffspec) && ...
    isfield(tffspec, 'ArrayFormat') && ...
    ischar(tffspec.ArrayFormat) && ...
    any(tffspec.ArrayFormat(:) == '%') && ...
    isfield(tffspec, 'CustomDelimiters') && ...
    iscell(tffspec.CustomDelimiters) && ...
    isfield(tffspec, 'Extensions') && ...
    iscell(tffspec.Extensions) && ...
    isfield(tffspec, 'FieldDelimCollapse') && ...
   ~isempty(tffspec.FieldDelimCollapse) && ...
    islogical(tffspec.FieldDelimCollapse) && ...
    isfield(tffspec, 'FieldDelimiters') && ...
    iscell(tffspec.FieldDelimiters) && ...
   ~isempty(tffspec.FieldDelimiters) && ...
    isfield(tffspec, 'LineDelimiters') && ...
    iscell(tffspec.LineDelimiters) && ...
   ~isempty(tffspec.LineDelimiters) && ...
    isfield(tffspec, 'ListOfFields') && ...
    isstruct(tffspec.ListOfFields) && ...
    isfield(tffspec, 'Loops') && ...
    isstruct(tffspec.Loops) && ...
    isfield(tffspec, 'Magic') && ...
    isstruct(tffspec.Magic) && ...
    isfield(tffspec, 'MaxFieldNameLength') && ...
    isnumeric(tffspec.MaxFieldNameLength) && ...
   ~isempty(tffspec.MaxFieldNameLength) && ...
    isfield(tffspec, 'ParagraphArrays') && ...
   ~isempty(tffspec.ParagraphArrays) && ...
    islogical(tffspec.ParagraphArrays) && ...
    isfield(tffspec, 'SkipEmptyLines') && ...
   ~isempty(tffspec.SkipEmptyLines) && ...
    islogical(tffspec.SkipEmptyLines) && ...
    isfield(tffspec, 'Variables') && ...
    isstruct(tffspec.Variables)

% any other struct is rejected
elseif isstruct(tffspec)
    error( ...
        'BVQXtools:BadArgument', ...
        'Invalid struct TFF specification.' ...
    );

% for character arrays
elseif ischar(tffspec)

    % valid file contents (0x0a/0x0d delimited)
    if any(tffspec == char(10) | tffspec == char(13)) || ...
        exist(tffspec, 'file') == 2

        % parse content
        try
            if writemode
                tffcont = tffio( ...
                    filename, ...
                    tffparse(tffspec), ...
                    varargin{:});
            else
                tffcont = tffio( ...
                    filename, ...
                    tffparse(tffspec), ...
                    varargin{:});
            end
            if ~writemode
                varargout{1} = tffcont;
            else
                if nargout > 0
                    varargout = cell(1, nargout);
                end
            end
            return;
        catch
            rethrow(lasterror);
        end
    end

    % otherwise
    error( ...
        'BVQXtools:BadArgument', ...
        'Invalid tffspec argument given.' ...
    );

end

% get shortcuts for specs
arf = tffspec.ArrayFormat;
fds = tffspec.FieldDelimiters;
ldc = double(tffspec.SkipEmptyLines(1));
lds = tffspec.LineDelimiters;
mfl = num2str(abs(floor(tffspec.MaxFieldNameLength(1))) + 1);
par = tffspec.ParagraphArrays(1);

% check specs
if isempty(regexpi(mfl, '^\d+$'))
    error( ...
        'BVQXtools:BadTFFSpec', ...
        'Invalid MaxFieldNameLength content.' ...
    );
end

% initialize rules variables
rule  = tffspec.ListOfFields;
rules = length(rule);

% get loops shortcut and prepare loopi struct, loopx
loops = tffspec.Loops;
loopf = fieldnames(loops);
if ~isempty(loopf)
    loopf = fieldnames(loops.(loopf{1}));
    loopi = cell2struct(cell(0, 0, length(loopf)), loopf, 3);
else
    loopi = struct;
end
loopx = {};

% get file extension
[fnamex{1:3}] = fileparts(filename);
fnamex = fnamex{3};
fnamex(fnamex == '.') = [];

% initialize output
if isempty(tffcont)
    tffcont = struct;
end

% initialize internal variables
namevars = struct;
namevars.TFFVERSION = tffversion;
namevars.TFFPATH    = fileparts(mfilename('fullpath'));
namevars.TFFREAD    = ~writemode;
namevars.TFFWRITE   =  writemode;
namevars.FILENAME   = filename;
namevars.EXTENSION  = fnamex;
namevars.NEXTLINE = 1;

% reading TFF content
if ~writemode

    % read entire file into 1xN char array
    try
        textcont = asciiread(filename);
    catch
        error( ...
            'BVQXtools:FileNotReadable', ...
            'File not readable: ''%s''.', ...
            filename ...
        );
    end

    % detect line delimiter
    for ldsc = 1:length(lds)
        if ~isempty(strfind(textcont, lds{ldsc}))
            lds = lds{ldsc};
            break;
        end
    end

    % no line delimiter found
    if ~ischar(lds)
        error( ...
            'BVQXtools:BadTFFCont', ...
            'No specified line delimiter detected.' ...
        );
    end

    % split to lines
    linecont  = splittocell(textcont, lds, ldc);
    if ldc && ...
       ~isempty(linecont) && ...
        isempty(linecont{1})
        linecont(1) = [];
    end
    linecont  = linecont(:);
    linecount = length(linecont);

    % get file "size"
    namevars.LINECOUNT = linecount;

% writing TFF content
else

    % BeforeWriteCode ?
    if ~isempty(tffspec.BeforeWriteCode)
        try
            eval(tff_parsecode(tffspec.BeforeWriteCode(:)'));
        catch
            error( ...
                'BVQXtools:EvaluationError', ...
                'Error raised by BeforeWriteCode: ''%s''.', ...
                lasterr ...
            );
        end
    end

    % create empty variables
    linecont  = {};
    linecount = 0;

    % get standard variables
    fds = fds{1};
    lds = lds{1};

end

% make sure to parse code only once
for rulec = 1:rules
    prule = rule(rulec);
    prule.cond = tff_parsecode(prule.cond);
    prule.dim = tff_parsecode(prule.dim);
    prule.varname = tff_parsecode(prule.varname);
    rule(rulec) = prule;
end

% grand loop
linec = 1;  % number of next line in file
rulec = 1;  % pointer to next rule to process
loopc = 0;  % counter of loops (in which loop are we)

% try used for forcemode (on indentation !!!)
try % forcemode

while rulec <= rules

    % get shortcut to current rule to process (and subfields)
    prule = rule(rulec);
    rtype = lower(prule.type);
    rfldn = prule.field;
    rdata = lower(prule.datatype);
    rcond = prule.cond;
    rdim  = prule.dim;
    rexpr = prule.varname;
    rform = prule.format;

    % try to resolve dim
    if isempty(rdim)
        rdim = 1;
    else
        try
            eval(['rdim=double([' rdim ']);']);
            if isempty(rdim) || ...
                size(rdim, 2) > 2
                error('BADDIM');
            end
        catch
            error( ...
                'BVQXtools:BadExpression', ...
                'Bad DIM expression: ''%s''.', ...
                prule.dim ...
            );
        end
    end

    % special case, flist & write is done by field!
    if writemode && ...
        strcmp(rtype, 'flist')
        rtype = 'field';
    end

    % what to do
    switch (rtype)

        % array
        case {'array'}

            % check cond
            if ~isempty(rcond)
                try
                    eval(['iofield=false;if ' rcond ',iofield=true;end']);
                catch
                    error( ...
                        'BVQXtools:BadExpression', ...
                        'Couldn''t evaluation COND expression: ''%s''.', ...
                        rcond ...
                    );
                end
                if ~iofield
                    rulec = rulec + 1;
                    continue;
                end
            end

            % check dim
            if length(rdim) ~= 2
                error( ...
                    'BVQXtools:BadTFFSpec', ...
                    'Dim for ARRAY must be 2-D.' ...
                );
            end
            rdimrows = rdim(1);
            rdimcols = rdim(2);

            % read access
            if ~writemode

                % initialize array
                rarray = zeros(rdim);

                % skip paragraphing line?
                if par && ...
                    ldc == 0
                    linec = lice + 1;
                end
                
                % skip empty column paragraph
                if rdimcols == 0 && ...
                    ldc
                    rdimrows = 0;

⌨️ 快捷键说明

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