update on WIP BSM class

This commit is contained in:
p147685 2020-03-28 08:29:41 +01:00
parent 20b2d4f22b
commit 3440e5b6d8
2 changed files with 134 additions and 21 deletions

View File

@ -52,21 +52,31 @@ classdef BSM<handle
if numel(SPMidx)>1
obj.SPMIndexList=SPMidx;
SPMidx=obj.SPMIndexList(end);
end
%% start dealing with val is a single entry
%% do the calculation
%% clean up
%% make SPMIndexList one shorter, return if not possible
%% next recursion loop.
warning('OFF', 'MATLAB:MKDIR:DirectoryExists');
%this try catch block will handle any errors that might ocure
%warning will not remain off by accident
try
obj.Calc(SPMidx); %handle the single case
catch ME
warning('ON', 'MATLAB:MKDIR:DirectoryExists');
rethrow(ME);
%if the identifier matches, just continue with next SPM
if ~any(strcmpi(ME.identifier,...
{'BSM:CoreCalc:SPMxBFOrder:invalid'...
,'BSM:CoreCalc:SPMSess:invalid'...
}))
rethrow(ME)
else
disp(ME.message);
end
end
obj.SPMIndexList=obj.SPMIndexList(1:end-1);
if isempty(obj.SPMIndexList)
return;
else
obj.Calc(obj.SPMIndexList);% recursively run the rest of the list
end
else % deal with single entry
obj.CoreCalc(SPMidx)
end
end
end
methods %constructor and set/get methods
function obj = BSM(varargin)
@ -146,6 +156,105 @@ classdef BSM<handle
end
end
methods %private functions
function CoreCalc(obj,idx)
fprintf('working on :%d: %s\n',idx,obj.SPMs{idx});
% how to store the current status of warning and restore curent
WarnStat=warning;
warning('OFF', 'MATLAB:MKDIR:DirectoryExists');
%this try catch block will handle any errors that might ocure
%warning will not remain off by accident
try
SpmFile=obj.SPMs{idx};
load(SpmFile); %#ok<LOAD>
%% exception block
%NB these exception has not been tested properly by the
if (SPM.xBF.order ~=1 )
%TestBSMClass program
%throw an error. The calling function should properly
%handle the error.
id='BSM:CoreCalc:SPMxBFOrder:invalid';
msg=sprintf('%s\n','Problem found', ...
'No canonical HRF was used to model the data', ...
'Current file will be skipped');
throw(MException(id,msg));
end
if (length(SPM.Sess) > 1 )
id='BSM:CoreCalc:SPMSess:invalid';
msg=sprintf('%s\n',...
'Problem found', ...
'Multiple sessions in one SPM.mat not supported', ...
'Current file will be skipped');
throw(MException(id,msg));
end
% end exception block
%% set local variables
SPMOrig = SPM;
UOrig = SPM.Sess(1).U;
[ActCol,PasCol,AllCol]=obj.GetColDef(UOrig);
LocalTargetFolder = fullfile(fileparts(SpmFile),'BSM');%RR replace BSM by a obj.BSMDir so user can modify this
%% create directory
mkdir(LocalTargetFolder);
% loop over ActCol
for c=1:length(ActCol)
% get current col, get other col
CurCol=ActCol(c);
OthCol=setdiff(1:length(ActCol),CurCol);
TargetFolderCurCol=fullfile(LocalTargetFolder,sprintf('col_%04d', CurCol));
for e=1:numel(UOrig(CurCol).ons)% loop over events
U=obj.GetU(UOrig,e,c)%build U
% build SPM
% process SPM
% Cleanup
end% end loop
% pack per event result
% Cleanup
end % end loop act. col
% restore warning status
warning(WarnStat);
catch ME %turn matlab warning back on
warning(WarnStat);
rethrow(ME);
end
end
function U=GetU(obj,UOrig,Event,Col)
U=struct('name',{},'ons', [], 'dur',[], 'P',[], 'dt', [], 'u', [],'pst',[]);
idx=1;
%split out current event as first condition
U(idx).name{1} = sprintf('%s_%d',UOrig(Col).name{1},Event);
U(idx).ons = UOrig(Col).ons(Event);
U(idx).dur = UOrig(Col).dur(Event);
U(idx).P = UOrig(Col).P;
U(idx).dt = UOrig(Col).dt;
%optional add all other events as the next condition
switch obj.Type
case {1,2}
idx = idx +1;
OtherTrials=setdiff(1:numel(UOrig(Col).ons),Event);
U(idx).name{1} = sprintf('%s_oe',UOrig(Col).name{1});
U(idx).ons = UOrig(Col).ons(OtherTrials);
U(idx).dur = UOrig(Col).dur(OtherTrials);
U(idx).P = UOrig(Col).P;
U(idx).dt = UOrig(Col).dt;
case {3,4}
otherwise
end
% deal with other conditions
switch obj.Type
case {1,4} %put all other conditions in one column
case {2,3} %keep other conditions each in their own column
otherwise
end
end
function [ActCol,PasCol,AllCol]=GetColDef(obj,U)
AllCol=1:length(U);
if ~isempty(obj.Acfl)
PasCol = AllCol(obj.Acfl); %cf line 53 in spm_bsm.m
else
PasCol = [];
end
ActCol = setdiff(AllCol,PasCol);
end
function set.SPMPath(obj,~)
SPMFound=which('spm'); %check if SPM in searchpath
if isempty(SPMFound) %SPM not found

View File

@ -1,4 +1,6 @@
%% This code will check the BSM class code in a very basic way.
%% BSM code validity check.
% This code will check the BSM class code in a very basic way.
%
%% create an instance
B=BSM;
%%
@ -92,3 +94,5 @@ catch ME
end
%%
B.Acfl=[];
%% Test Calc routine
B.Calc