📄 prt_cleanup.m
字号:
function hfile = prt_CleanUp(hfile, varargin)
% PRT::CleanUp - clean up protocols
%
% FORMAT: [prt] = prt.CleanUp([fullclean]);
%
% Input fields:
%
% fullclean if given and true, perform full cleanup
%
% Output fields:
%
% prt altered PRT
% Version: v0.7b
% Build: 7090213
% Date: Sep-02 2007, 1:08 PM CET
% Author: Jochen Weber, Brain Innovation, B.V., Maastricht, NL
% URL/Info: http://wiki.brainvoyager.com/BVQXtools
% argument check
if nargin < 1 || ...
numel(hfile) ~= 1 || ...
~isBVQXfile(hfile, 'prt')
error( ...
'BVQXfile:BadArgument', ...
'Invalid call to %s.', ...
mfilename ...
);
end
bc = bvqxfile_getcont(hfile.L);
if nargin > 1 && ...
(isa(varargin{1}, 'double') || islogical(varargin{1})) && ...
~isempty(varargin{1}) && ...
varargin{1}(1)
fullclean = true;
else
fullclean = false;
end
% get settings
ncon = numel(bc.Cond);
if ~isempty(bc.ResolutionOfTime) && ...
lower(bc.ResolutionOfTime(1)) == 'm'
tresms = 1;
tresvol = 0;
else
tresms = 0;
tresvol = 1;
end
% loop over number of conditions
lastend = 0;
for cc = ncon:-1:1
% get condition, update last end
c = bc.Cond(cc);
bc.Cond(cc).NrOfOnOffsets = size(c.OnOffsets, 1);
% skip empty conditions
if isempty(c.OnOffsets)
if fullclean
bc.Cond(cc) = [];
end
continue;
end
% update last index and set changed flag
lastend = max(lastend, max(c.OnOffsets(:, 2)));
% loop over onsets, starting at the end
for oc = c.NrOfOnOffsets:-1:2
% check intervals
if (c.OnOffsets(oc - 1, 2) + 1) >= c.OnOffsets(oc, 1)
% give warning ?
if (c.OnOffsets(oc - 1, 2) + tresvol) > c.OnOffsets(oc, 1)
warning( ...
'BVQXfile:ProtocolWarning', ...
'Overlapping stimulus durations in same condition.' ...
);
end
% concatenate epochs
c.OnOffsets(oc, 1) = c.OnOffsets(oc - 1, 1);
c.OnOffsets(oc - 1, :) = [];
end
end
% put back
c.NrOfOnOffsets = size(c.OnOffsets, 1);
bc.Cond(cc) = c;
end
% update number of conditions
if fullclean
ncon = numel(bc.Cond);
bc.NrOfConditions = ncon;
end
% that's it ?
if ~fullclean || ...
ncon < 1
return;
end
% get old conditions
ocond = bc.Cond;
oc1 = ocond(1);
% otherwise create a new protocol and copy initial settings
nbc = BVQXfile(0, 'newcont', 'prt');
nbc.FileVersion = bc.FileVersion;
nbc.ResolutionOfTime = bc.ResolutionOfTime;
nbc.Experiment = bc.Experiment;
nbc.BackgroundColor = bc.BackgroundColor;
nbc.TextColor = bc.TextColor;
nbc.TimeCourseColor = bc.TimeCourseColor;
nbc.TimeCourseThick = bc.TimeCourseThick;
nbc.ReferenceFuncColor = bc.ReferenceFuncColor;
nbc.ReferenceFuncThick = bc.ReferenceFuncThick;
nbc.Cond = oCond;
nbc.Cond(:) = [];
% get combined list and matrix of on/offsets
iact = uint8(0);
iact(1:ncon, 1:lastend) = iact(1);
for cc = 1:ncon
c = ocond(cc);
onum = c.NrOfOnOffsets;
for oc = 1:onum
iact(cc,(c.OnOffsets(oc,1)+tresms):(c.OnOffsets(oc,2))) = uint8(1);
end
end
numc = sum(iact);
% resting condition ?
rest = (numc == 0);
if any(rest)
% get rest on/offsets
ron = 1 + find(diff(rest) > 0);
roff = 1 + find(diff(rest) < 0);
if isempty(roff)
roff = length(rest);
end
if isempty(ron) || ...
ron(1) > roff(1)
ron = [1, ron];
end
if roff(end) < ron(end)
roff(end + 1) = length(rest);
end
numrest = length(ron);
if numrest ~= length(roff)
error( ...
'BVQXfile:InternalError', ...
'Mishap when figuring out rest phases.' ...
);
end
ronoff = zeros(numrest, 2);
for rc = 1:numrest
ronoff(cc, :) = [ron, roff - tresvol];
end
% add rest to new file (first condition)
disp(sprintf(' -> adding ''Rest'' condition with %d onsets', numrest));
oc1.ConditionName = 'Rest';
oc1.NrOfOnOffsets = size(ronoff, 1);
oc1.OnOffsets = ronoff;
oc1.Color = [32, 32, 32];
nbc.Cond(end + 1) = oc1;
else
% add rest with no onsets
disp(' -> adding ''Rest'' condition with 0 onsets');
oc1.ConditionName = 'Rest';
oc1.NrOfOnOffsets = 0;
oc1.OnOffsets = zeros(0, 2);
oc1.Color = [32, 32, 32];
nbc.Cond(end + 1) = oc1;
end
clear rest;
% find overlap between one .. ncon conditions
for cc = 1:max(numc)
% scan conditions
for scc = 1:ncon
% find where numc == cc and condition(scc) is on
ciact = diff([false, (numc == cc & (iact(scc, :) > 0)), false]);
ciaon = find(ciact > 0) - tresms;
ciaoff = find(ciact < 0) - 1;
% check length
if length(ciaon) ~= length(ciaoff)
error( ...
'BVQXfile:InternalError', ...
'Error finding non-interaction periods.' ...
);
end
% do nothing on emtpy array
if isempty(ciaon)
continue;
end
% no interaction
if cc == 1
% put into new file
disp(sprintf(' -> keeping condition ''%s'' with %d onset(s)', ...
deblank(ocond(scc).ConditionName{1}), length(ciaon)));
nfile = prt_AddCond(nfile, ...
deblank(ocond(scc).ConditionName{1}), ...
[ciaon(:), ciaoff(:)], ...
ocond(scc).Color);
iact(cc, (numc == cc & (iact(scc, :) > 0))) = false;
continue;
end
% repeat until interactions of level cc with condition(scc) OK
while ~isempty(ciaon)
% get "on" conditions on first onset
oncon = find(iact(:, ciaon(1) + tresms) > 0);
if length(oncon) ~= cc
error( ...
'BVQXfile:InternalError', ...
'Error looking up interaction conditions.' ...
);
end
% find phases where sum == cc and sum(oncon) == cc !
siact = diff([false, (numc == cc & sum(iact(oncon(:)', :)) == cc), false]);
siaon = find(siact > 0) - tresms;
siaoff = find(siact < 0) - 1;
% check length
if length(siaon) ~= length(siaoff) || ...
isempty(siaon)
error( ...
'BVQXfile:InternalError', ...
'Error finding interaction periods.' ...
);
end
% building new name
newname = cell(1, numel(oncon));
newcol = zeros(1, 3);
for sscc = oncon(:)'
newname{sscc} = deblank(ocond(sscc).ConditionName{1});
newcol = newcol + ocond(sscc).Color;
end
newname = sprintf('Interaction (%s)', ...
gluetostring(newname, ' & '));
newcol = round(newcol / cc);
% put into new file
disp(sprintf(' -> building interaction ''%s'' with %d onset(s)', ...
newname, length(siaon)));
oc1.Name = newname;
oc1.NrOfOnOffsets = numel(siaon);
oc1.OnOffsets = [siaon(:), siaoff(:)];
oc1.Color = newcol;
nbc.Cond(end + 1) = oc1;
% remove from array
for soc = 1:length(siaon)
iact(oncon(:)', siaon(soc)+tresms:siaoff(soc)) = false;
end
% do find again to get loop right
numc = sum(iact);
ciact = diff([false, (numc == cc & (iact(scc, :) > 0)), false]);
ciaon = find(ciact > 0) - tresms;
ciaoff = find(ciact < 0) - 1;
% check length
if length(ciaon) ~= length(ciaoff)
error( ...
'BVQXfile:InternalError', ...
'Error finding non-interaction periods.' ...
);
end
end
end
end
% overwrite old with new content
bvqxfile_setcont(hfile.L, nbc);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -