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

📄 readpar.m

📁 toolbox of BVQX, This is the access between BV and matlab. It will help you to analysis data from BV
💻 M
字号:
function par = readpar(filename)
% readpar  - read a Philips PAR file
%
% FORMAT:       par = readpar(filename)
%
% Input fields:
%
%       filename    PAR filename
%
% Output fields:
%
%       par         1x1 struct with PAR contents
%
% See also transio

% Version:  v0.6c
% Build:    7012311
% Date:     Jan-23 2007, 11:05 AM CET
% Author:   Jochen Weber, Brain Innovation, B.V., Maastricht, NL
% URL/Info: http://wiki.brainvoyager.com/BVQXtools

% enough arguments ?
if nargin < 1 || ...
   ~ischar(filename) || ...
    isempty(filename) || ...
    exist(filename(:)', 'file') ~= 2
    error( ...
        'BVQXtools:BadArguments',...
        'Bad argument or file not found.' ...
    );
end
filename = filename(:)';

% try read
try
    parcont = asciiread(filename);
catch
    error( ...
        'BVQXtools:FileNotReadable', ...
        'File not readable: ''%s''.', ...
        filename ...
    );
end

% preliminary parse content
parlines = splittocell(parcont, char([10, 13]), 1, 1);
if length(parlines) < 30
    error( ...
        'BVQXtools:BadFileContent', ...
        'Too few lines in file.' ...
    );
end
slline = grep(parlines, '-ixl', 'sl\s+ec\s+dyn');
if numel(slline) ~= 1 || ...
    slline < 30
    error( ...
        'BVQXtools:BadFileContent', ...
        'Line with ''#sl ec dyn ...'' tokens not found or too early.' ...
    );
end

% prepare output
par = struct;
par.PARFile = filename;

% remove comment lines from first part
parset = parsesetlines(grep(parlines(1:slline - 1), '-vx', '^\#'), '^\.\s+');
par.Parameters = parset;
parnames = fieldnames(parset);

% find settings in par set
noslices = findfield(parnames, {'slice', 'number'});
nodynamics = findfield(parnames, {'dynamic', 'number'});
noechoes = findfield(parnames, {'echo', 'number'});

% check settings
if isempty(noslices) || ...
    isempty(nodynamics)
    error( ...
        'BVQXtools:BadFileContent', ...
        'Either number of slices or number of dynamics not found.' ...
    );
end
noslices = parset.(noslices);
nodynamics = parset.(nodynamics);
if ~isempty(noechoes)
    noechoes = parset.(noechoes);
else
    noechoes = 1;
end
nodynsliech = prod([nodynamics, noslices, noechoes]);

% image definition
imglines = grep(parlines, '-ix', '^#\s+.*(float|integer|string)\)\s*$');
imgset = parsesetlines(imglines, '^#\s+');
par.ImageParameters = imgset;
imgnames = fieldnames(imgset);
imgnum = length(imgnames);

% build correct representation
imghead = {};
for cc = imgnum:-1:1
    limgname = lower(imgnames{cc});
    limgset = lower(imgset.(imgnames{cc}));
    [li_t{1:3}] = regexp(limgset, '^\((\d+)\*[a-z]+\)$');
    li_t = li_t{3};
    if ~isempty(li_t) && ...
        numel(li_t{1}) == 2
        try
            addnumber = str2double(limgset(li_t{1}(1):li_t{1}(2)));
            imgnum = imgnum + addnumber - 1;
            for ac = addnumber:-1:2
                imghead = [{sprintf('%s_%d', limgname, ac)}; imghead(:)];
            end
        catch
            % nothing
        end
        imghead = [{[limgname '_1']}; imghead(:)];
    else
        imghead = [{limgname}; imghead(:)];
    end
end
imgnames = imghead;
imgnum = length(imgnames);

% find settings in img set
sliceno = findfield(imgnames, {'slice', 'number'});
dynamicno = findfield(imgnames, {'dynamic', 'number'});
pixres = findfield(imgnames, {'pixel', 'size'});
imgres = findfield(imgnames, {'resolution'});
imgidx = findfield(imgnames, {'index', 'rec'});

% check settings
if isempty(sliceno) || ...
    isempty(dynamicno) || ...
    isempty(pixres) || ...
    isempty(imgres)
    error( ...
        'BVQXtools:BadFileContent', ...
        'Required image header fields not found.' ...
    );
end
sliceno = find(strcmp(imgnames, sliceno));
dynamicno = find(strcmp(imgnames, dynamicno));
pixres = find(strcmp(imgnames, pixres));
imgres = find(strcmp(imgnames, imgres));

% try conversion
vallines = grep(grep(parlines(slline + 1:end), '-vx', '^#'), '-vx', '^$');
valmatrix = zeros(length(vallines), imgnum);
eval(['valmatrix(:,:)=[' gluetostring(vallines, ';') '];'], 'valmatrix=[];');
if size(valmatrix, 1) ~= length(vallines)
    error( ...
        'BVQXtools:BadFileContent', ...
        'Error converting value lines in PAR file.' ...
    );
end
if size(valmatrix, 2) ~= imgnum
    error( ...
        'BVQXtools:BadFileContent', ...
        'Value matrix header line inconsistent.' ...
    );
end
par.MatrixHeaders = imghead;
par.MatrixValues = valmatrix;

% try to locate REC file
[fpath, fname] = fileparts(filename);
if numel(fpath) > 0 && ...
    fpath(end) ~= filesep
    fpath = [fpath filesep];
end
fpath = [fpath fname];
if exist([fpath '.REC'], 'file') == 2
    rfile = [fpath '.REC'];
elseif exist([fpath '.rec'], 'file') == 2
    rfile = [fpath '.rec'];
else
    return;
end
par.RECFile = rfile;

% check pix/img res
if any(diff(valmatrix(:, pixres(1)))) || ...
    any(diff(valmatrix(:, imgres(1)))) || ...
    any(diff(valmatrix(:, imgres(1) + 1)))
    warning( ...
        'BVQXtools:FileContNoSupported', ...
        'Unequal image resolutions over time!' ...
    );
    return;
end

% try to guess indexing order
useidx = false;
if ~isempty(imgidx)
    imgidx = find(strcmp(imgnames, imgidx));
    if ~isempty(imgidx)
        [uimgidx, iuimgidx] = unique(valmatrix(:, imgidx(1)));
        if length(uimgidx) == size(valmatrix, 1)
            useidx = true;
        end
    end
end
par.UseIndex = useidx;

% check remaining line number
if size(valmatrix, 1) == (noslices * nodynamics * noechoes)
    
    % get dynslc array
    if useidx
        dynslc = valmatrix(iuimgidx(:)', [dynamicno(1), sliceno(1)]);
        par.RECDataType = 'Dyn.Slice';
    else
        dynslc = valmatrix(:, [dynamicno(1), sliceno(1)]);
        par.RECDataType = 'Slice';
    end
else
    if useidx
        dynslc = iuimgidx(:) - 1;
        par.RECDataType = 'Slice';
    else
        dynslc = size(valmatrix, 1);
        par.RECDataType = 'Chunk';
    end
end

% calculate image size and class
pixres = valmatrix(1, pixres(1));
switch (pixres)
    case {8},  dcls = 'uint8';
    case {16}, dcls = 'int16';
    case {32}, dcls = 'single';
    case {64}, dcls = 'double';
    otherwise
        warning( ...
            'BVQXtools:FileContNoSupported', ...
            'Pixel bitsize of %d not supported.', ...
            valmatrix(1, pixres(1)) ...
        );
end
pixres = pixres / 8;
imgdims = valmatrix(1, imgres(1):imgres(1)+1);
imgsize = prod(imgdims) * pixres;
par.BytePerPixel = pixres;
par.SliceResolution = imgdims;

% try to create object
try
    if useidx
        if size(dynslc, 2) > 1
            transio(rfile, 'ieee-le', 'uint8', 0, [nodynsliech, imgsize]);
            for ic = 1:size(dynslc, 1)
                par.RECData.Dyn(dynslc(ic, 1)).Slice(dynslc(ic, 2)).IO = ...
                    transio(rfile, 'ieee-le', dcls, (ic - 1) * imgsize, imgdims);
            end
        else
            for ic = 1:length(dynslc)
                par.RECData.Slice(ic).IO = ...
                    transio(rfile, 'ieee-le', dcls, dynslc(ic) * imgsize, imgdims);
            end
        end
    else
        if length(dynslc) > 1
            for ic = 1:length(dynslc)
                par.RECData.Slice(ic).IO = ...
                    transio(rfile, 'ieee-le', dcls, (ic - 1) * imgsize, imgdims);
            end
        else
            par.RECData.Chunk.IO = ...
                transio(rfile, 'ieee-le', dcls, 0, [dynslc, imgdims]);
        end
    end
catch
    if isfield(par, 'RECData')
        par = rmfield(par, 'RECData');
    end
end

% %%% subfunctions


function setstr = parsesetlines(setlines, lineprefix)
    setstr = struct;
    for lc = 1:length(setlines)
        setline = setlines{lc};
        if ~isempty(setline) && ...
            ~isempty(regexpi(setline, lineprefix))
            setline = mstrrep(setline, {lineprefix, '\s+'}, {'', ' '}, 1);
            colonpos = find(setline == ':');
            if numel(colonpos) == 1 && ...
                colonpos > 1
                labline = makelabel(deblank(regexprep(setline(1:colonpos - 1), ...
                    '[^a-zA-Z\s\.].*$', '')));
                valline = mstrrep(setline(colonpos + 1:end), ...
                    {'^\s+', '\s+$'}, {'', ''}, 1);
            else
                setlinec = splittocell(setline, char([9, 32]), 1, 1);
                if length(setlinec) < 2
                    continue;
                end
                labline = makelabel(deblank(regexprep(gluetostring( ...
                    setlinec(1:end-1), ' '), '[^a-zA-Z_\s\.].*$', '')));
                valline = setlinec{end};
            end
            if length(labline) < 2 || ...
                (any('vV' == labline(1)) && labline(2) == '_')
                continue;
            end
            vallineok = regexp(valline, '^[0-9\+\-e\.\s]+$');
            if ~isempty(vallineok) && ...
               (isa(vallineok, 'double') || ...
                (iscell(vallineok) && ~isempty(vallineok{1})))
                try
                    valline = eval(['[' valline ']']);
                catch
                    valline = 0;
                end
            end
            setstr.(labline) = valline;
        end
    end
% end of function setstr = parsesetlines(setlines)

function fname = findfield(fnames, parts)
    lfnames = lower(fnames);
    if ~iscell(parts)
        parts = {parts};
    end
    parts = lower(parts);
    pnum = length(parts);
    for fc = 1:length(fnames)
        fmatch = true;
        for pc = 1:pnum
            if isempty(strfind(lfnames{fc}, parts{pc}))
                fmatch = false;
                break;
            end
        end
        if fmatch
            fname = fnames{fc};
            return;
        end
    end
    fname = '';
% end of function fname = findfield(fnames, parts)

⌨️ 快捷键说明

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