📄 vmr_update.m
字号:
function hfile = vmr_Update(hfile, F, S, V)
% VMR::Update - called after subsasgn for VMRs
% Version: v0.7b
% Build: 7083012
% Date: Aug-30 2007, 12:29 PM CEST
% Author: Jochen Weber, Brain Innovation, B.V., Maastricht, NL
% URL/Info: http://wiki.brainvoyager.com/BVQXtools
% persistent config
persistent bvqxfile_vmrconfig;
if isempty(bvqxfile_vmrconfig)
bvqxfile_vmrconfig = struct;
bvqxfile_vmrconfig.fields = cell(1,4);
bvqxfile_vmrconfig.fields{1} = ...
{'FileVersion', 'NrOfCrossCorrLags', ...
'DimX', 'DimY', 'DimZ', 'VMR8bit', 'VMRData', ...
'VMRData16', 'OffsetX', 'OffsetY', 'OffsetZ', 'FramingCube'};
bvqxfile_vmrconfig.fields{2} = ...
{'FileVersion', 'DimX', 'DimY', 'DimZ', 'VMR8bit', 'VMRData', ...
'VMRData16', 'OffsetX', 'OffsetY', 'OffsetZ', 'FramingCube'};
bvqxfile_vmrconfig.fields{3} = ...
{'FileVersion', 'DimX', 'DimY', 'DimZ', 'VMR8bit', 'VMRData', ...
'VMRData16', 'OffsetX', 'OffsetY', 'OffsetZ', 'FramingCube', ...
'PosInfoVerified', 'CoordinateSystem', ...
'Slice1CenterX', 'Slice1CenterY', 'Slice1CenterZ', ...
'SliceNCenterX', 'SliceNCenterY', 'SliceNCenterZ', ...
'RowDirX', 'RowDirY', 'RowDirZ', 'ColDirX', 'ColDirY', 'ColDirZ', ...
'NRows', 'NCols', 'FoVRows', 'FoVCols', ...
'SliceThickness', 'GapThickness', 'NrOfPastSpatialTransformations', ...
'Convention', 'VoxResX', 'VoxResY', 'VoxResZ', ...
'VoxResInTalairach', 'VoxResVerified', ...
'MinOriginalValue', 'MeanOriginalValue', 'MaxOriginalValue'};
bvqxfile_vmrconfig.fields{4} = ...
{'FileVersion', 'DimX', 'DimY', 'DimZ', 'VMR8bit', 'VMRData', ...
'OffsetX', 'OffsetY', 'OffsetZ', 'FramingCube', ...
'PosInfoVerified', 'CoordinateSystem', ...
'Slice1CenterX', 'Slice1CenterY', 'Slice1CenterZ', ...
'SliceNCenterX', 'SliceNCenterY', 'SliceNCenterZ', ...
'RowDirX', 'RowDirY', 'RowDirZ', 'ColDirX', 'ColDirY', 'ColDirZ', ...
'NRows', 'NCols', 'FoVRows', 'FoVCols', ...
'SliceThickness', 'GapThickness', 'NrOfPastSpatialTransformations', ...
'Convention', 'VoxResX', 'VoxResY', 'VoxResZ', ...
'VoxResInTalairach', 'VoxResVerified', ...
'MinOriginalValue', 'MeanOriginalValue', 'MaxOriginalValue'};
bvqxfile_vmrconfig.defaults = struct( ...
'NrOfCrossCorrLags', 0, ...
'OffsetX', 0, ...
'OffsetY', 0, ...
'OffsetZ', 0, ...
'VMR8bit', true, ...
'FramingCube', '!256 * (1 + double((max(max(@DimX, @DimY), @DimZ) > 256)))!', ...
'PosInfoVerified', 0, ...
'CoordinateSystem', 0, ...
'Slice1CenterX', 0, ...
'Slice1CenterY', 0, ...
'Slice1CenterZ', '!- @DimZ/2!', ...
'SliceNCenterX', 0, ...
'SliceNCenterY', 0, ...
'SliceNCenterZ', '!@DimZ/2!', ...
'RowDirX', 1, ...
'RowDirY', 0, ...
'RowDirZ', 0, ...
'ColDirX', 0, ...
'ColDirY', 1, ...
'ColDirZ', 0, ...
'NRows', '!@DimX!', ...
'NCols', '!@DimY!', ...
'FoVRows', '!@DimX!', ...
'FoVCols', '!@DimY!', ...
'SliceThickness', 1, ...
'GapThickness', 0, ...
'NrOfPastSpatialTransformations', cell2struct(cell(0, 0, 5), ...
{'NameOfSpatialTransformation', ...
'TypeOfSpatialTransformation', ...
'SourceFileOfSpatialTransformation', ...
'NrOfSpatialTransformationValues', ...
'TransformationValues'}, 3), ...
'Convention', 1, ...
'VoxResX', 1, ...
'VoxResY', 1, ...
'VoxResZ', 1, ...
'VoxResInTalairach', 0, ...
'VoxResVerified', 0, ...
'MinOriginalValue', 0, ...
'MeanOriginalValue',127, ...
'MaxOriginalValue', 255);
end
% argument check
if nargin < 2 || ...
~all(isBVQXfile(hfile(:), 'vmr')) || ...
~ischar(F) || ...
isempty(F)
error( ...
'BVQXfile:BadArgument', ...
'Invalid call to %s.', ...
mfilename ...
);
end
if nargin < 3 || ...
~isstruct(S)
S = struct;
S.type = '.';
S.subs = F;
end
if nargin < 4
V = [];
end
% get content
bc = bvqxfile_getcont(hfile.L);
% linearize
F = makelabel(F(:)');
% F valid
if ~isfield(bc, F)
error( ...
'BVQXfile:InvalidProperty', ...
'Cannot find property ''%s'' for type VMR.', ...
F ...
);
end
% what field has changed
switch (lower(F))
% reframing
case {'dimx', 'dimy', 'dimz'}
% which target type
if bc.VMR8bit
is8bit = true;
else
is8bit = false;
end
% get destination and current data size
dsize = [bc.DimX, bc.DimY, bc.DimZ];
csize = size(bc.VMRData);
% changes ?
if any(dsize ~= csize)
% dim1
if dsize(1) < csize(1)
srange1 = round(0.5 + (csize(1) - dsize(1)) / 2);
srange1(2) = srange1 + dsize(1) - 1;
trange1 = [1, dsize(1)];
elseif dsize(1) > csize(1)
srange1 = [1, csize(1)];
trange1 = round(0.5 + (dsize(1) - csize(1)) / 2);
trange1(2) = trange1 + csize(1) - 1;
else
srange1 = [1, csize(1)];
trange1 = srange1;
end
% dim2
if dsize(2) < csize(2)
srange2 = round(0.5 + (csize(2) - dsize(2)) / 2);
srange2(2) = srange2 + dsize(2) - 1;
trange2 = [1, dsize(2)];
elseif dsize(2) > csize(2)
srange2 = [1,csize(2)];
trange2 = round(0.5 + (dsize(2) - csize(2)) / 2);
trange2(2) = trange2 + csize(2) - 1;
else
srange2 = [1, csize(2)];
trange2 = srange2;
end
% dim3
if dsize(3) < csize(3)
srange3 = round(0.5 + (csize(3) - dsize(3)) / 2);
srange3(2) = srange3 + dsize(3) - 1;
trange3 = [1, dsize(3)];
elseif dsize(3) > csize(3)
srange3 = [1,csize(3)];
trange3 = round(0.5 + (dsize(3) - csize(3)) / 2);
trange3(2) = trange3 + csize(3) - 1;
else
srange3 = [1, csize(3)];
trange3 = srange3;
end
% get source data
VMRsrc = bc.VMRData( ...
srange1(1):srange1(2), ...
srange2(1):srange2(2), ...
srange3(1):srange3(2));
% create target data
if is8bit
bc.VMRData = uint8(0);
else
bc.VMRData = uint16(0);
end
bc.VMRData(1:dsize(1), 1:dsize(2), 1:dsize(3)) = 0;
% put source in target
bc.VMRData( ...
trange1(1):trange1(2), ...
trange2(1):trange2(2), ...
trange3(1):trange3(2)) = VMRsrc;
end
% changing file version
case {'fileversion'}
% get wanted version
reqv = bc.FileVersion;
% check version
if isempty(reqv) || ...
~isa(reqv, 'double') || ...
isnan(reqv(1)) || ...
isinf(reqv(1)) || ...
fix(reqv(1)) ~= reqv(1) || ...
reqv(1) < 0 || ...
reqv(1) > 3
% give warning if required
warning( ...
'BVQXfile:InvalidPropertyValue', ...
'Invalid FileVersion value given.' ...
);
% set better value and go on
reqv = 3;
bc.FileVersion = reqv;
end
% get good field list
goodf = bvqxfile_vmrconfig.fields{reqv + 1};
deffc = bvqxfile_vmrconfig.defaults;
% iterate over existing fields and remove all superfluous first
hasf = fieldnames(bc);
for fc = 1:length(hasf)
if ~any(strcmp(hasf{fc}, goodf))
bc = rmfield(bc, hasf{fc});
end
end
% iterate over goodf and add default for any missing
for fc = 1:length(goodf)
if ~any(strcmp(goodf{fc}, hasf))
goodv = deffc.(goodf{fc});
if ischar(goodv) && ...
~isempty(goodv) && ...
goodv(1) == '!' && ...
goodv(end) == '!' && ...
any(goodv == '@')
try
eval(['goodv=' ...
strrep(goodv(2:end-1), '@', 'bc.') ...
';']);
catch
warning( ...
'BVQXfile:EvaluationError', ...
'Error evaluating default value for %s: %s.', ...
goodf{fc}, deffc.(goodf{fc}) ...
);
goodv = [];
end
end
bc.(goodf{fc}) = goodv;
end
end
% set to 8 bit (max intensity 223)
case {'vmr8bit'}
% get target state
tt = bc.VMR8bit;
if isempty(tt)
tt = false;
elseif ~isnumeric(tt)
tt = true;
elseif tt(1)
tt = true;
else
tt = false;
end
% only check type for 8bit (other is checked in VMRData handler)
if tt && ...
~isa(bc.VMRData, 'uint8')
% set and find maxval
maxval = 223;
curmax = double(max(bc.VMRData(:)));
% only reset if greater than possible values!
if curmax > 255
% recalculate intensities
bc.VMRData = uint8(round( ...
double(bc.VMRData) * (maxval/curmax)));
% else just adapt datatype
elseif ~isa(bc.VMRData, 'uint8')
% set datatype
bc.VMRData = uint8(bc.VMRData);
end
end
% if ~tt and ~uint16
if ~tt && ...
~isa(bc.VMRData, 'uint16')
% set datatype
bc.VMRData = uint16(bc.VMRData);
end
% new data set (either partial or complete!)
case {'vmrdata'}
% get current datatype
if bc.VMR8bit
is8bit = true;
maxval = uint8(255);
else
is8bit = false;
maxval = uint16(4095);
end
% check type
checkcont = false;
if is8bit
if ~isa(bc.VMRData, 'uint8')
checkcont = true;
end
else
if ~isa(bc.VMRData, 'uint16')
checkcont = true;
end
end
% if type must be converted
if checkcont
% check numeric content
if ~isnumeric(bc.VMRData)
% give warning
warning( ...
'BVQXfile:InvalidDataType', ...
'Invalid datatype for VMRData property.' ...
);
% and fill with type according zeros
csize = [bc.DimX, bc.DimY, bc.DimZ];
if is8bit
bc.VMRData = uint8(0);
else
bc.VMRData = uint16(0);
end
bc.VMRData(1:csize(1), 1:csize(2), 1:csize(3)) = 0;
else
% replace NaN's and Inf's
bc.VMRData(isnan(bc.VMRData)) = 0;
bc.VMRData(isinf(bc.VMRData)) = maxval;
% get min and max val
curmin = double(min(bc.VMRData(:)));
if curmin > 0
curmin = 0;
end
curmax = double(max(bc.VMRData(:)));
% reframe intensities
if is8bit
if curmax > 255
maxval = uint8(223);
end
bc.VMRData = uint8(round( ...
(double(bc.VMRData) - curmin) / ...
(curmax + eps - curmin) * double(maxval)));
else
bc.VMRData = uint16(round( ...
(double(bc.VMRData) - curmin) / ...
(curmax + eps - curmin) * double(maxval)));
end
end
end
% get source and current data size
ssize = [bc.DimX, bc.DimY, bc.DimZ];
csize = size(bc.VMRData);
% changes ?
if any(ssize ~= csize)
bc.DimX = csize(1);
bc.DimY = csize(2);
bc.DimZ = csize(3);
end
end
% update contents
bvqxfile_setcont(hfile.L, bc);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -