From 20b2d4f22b385379e9eefda06dcd72cc790d4bb6 Mon Sep 17 00:00:00 2001 From: p147685 Date: Thu, 26 Mar 2020 07:10:38 +0100 Subject: [PATCH] Store BSMclass work in progress --- resources/BSM_Class/BSM.m | 175 +++++++++++++++++++++++++++++ resources/BSM_Class/TestBSMClass.m | 94 ++++++++++++++++ 2 files changed, 269 insertions(+) create mode 100644 resources/BSM_Class/BSM.m create mode 100644 resources/BSM_Class/TestBSMClass.m diff --git a/resources/BSM_Class/BSM.m b/resources/BSM_Class/BSM.m new file mode 100644 index 0000000..af3d638 --- /dev/null +++ b/resources/BSM_Class/BSM.m @@ -0,0 +1,175 @@ +classdef BSMobj.NumSPMs + id='BSM:Calc:InvalidIndex'; + msg='Invalid Index'; + throw(MException(id,msg)); + end + 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 + catch ME + warning('ON', 'MATLAB:MKDIR:DirectoryExists'); + rethrow(ME); + end + end + end + methods %constructor and set/get methods + function obj = BSM(varargin) + %BSM Construct an instance of this class + %option: parse the info of a matlab batch file? see + %tbx_cf_bsm? + %TODO: + % set default values + obj.SPMPath=[]; %get the SPM path + if nargin>0 + [val,TF]=obj.MyGetVal('SPMs',varargin);if TF;obj.SPMs=val;end + [val,TF]=obj.MyGetVal('Type',varargin);if TF;obj.Type=val;end + [val,TF]=obj.MyGetVal('Acfl',varargin);if TF;obj.Acfl=val;end + end + % initialize spm job enviourment + spm_jobman('initcfg'); + end + function val=get.NumSPMs(obj) + val=numel(obj.SPMs); + end + function set.Type(obj,val) + %check allowed input + if ~isnumeric(val)|| any(~ismember(val,1:5)) + id='BSM:Type:invalid'; + msg='use a value in the range 1..5'; + throw(MException(id,msg)); + end + obj.Type=val; + end + function set.Acfl(obj,val) + %allow clearing + if isempty(val) + obj.Acfl=[]; + end + if ~isnumeric(val) || any(val<1) || any(~isfinite(val)) + id='BSM:Acfl:invalid'; + msg='set an array of positive integer values to the Acfl field'; + throw(MException(id,msg)); + end + obj.Acfl=val; + + end + function set.SPMs(obj,val) + %set the SPMs to be analysed + %obj.SPMs= + %possible values for + % {} : clear the SPMs field + % {'ui'} : ask user input + if ~iscell(val) + fprintf('%s\n',... + 'Use any of the following options',... + 'obj.SPMs={}',... + 'obj.SPMs={''ui''}',... + 'obj.SPMs={}'); + return + end + if isempty(val) %allow empty input + return; + end + if strcmpi(val{1},'ui') + [P,sts]=spm_select([1 Inf],'mat','select the SPM.mat files',obj.SPMs,pwd,'^SPM.mat'); + if ~logical(sts);return;end + if iscell(P) + val=P; + else + val=cellstr(P); + end + end + % capture file not found somewhat clever + TF=cellfun(@exist,val); + if any(not(TF)) + id='BSM:SetSPMs:FileNotFound'; + msg=sprintf('file not found\t%s\n',val{not(TF)}); + throw(MException(id,msg)); + end + obj.SPMs=val; + end + end + methods %private functions + function set.SPMPath(obj,~) + SPMFound=which('spm'); %check if SPM in searchpath + if isempty(SPMFound) %SPM not found + error('please add SPM to your path before trying to run BSM'); + %to do add a check on spm version + end + obj.SPMPath=fileparts(SPMFound); + end + function[val,TF]=MyGetVal(~,selector,List) + TF=strcmpi(selector,List); + if any(TF) %spmpath is set as option + k=find(TF, 1 );%find the first instance + if (k+1)>numel(List) + id='BSM:getval:ReadBeyondEndInput'; + msg=sprintf('use name value pairs\nlast entry is a name'); + throw(MException(id,msg)); + end + val=List{k+1}; + TF=true; + else + val=false; + TF=false; + end + end + end +end + diff --git a/resources/BSM_Class/TestBSMClass.m b/resources/BSM_Class/TestBSMClass.m new file mode 100644 index 0000000..e4580e1 --- /dev/null +++ b/resources/BSM_Class/TestBSMClass.m @@ -0,0 +1,94 @@ +%% This code will check the BSM class code in a very basic way. +%% create an instance +B=BSM; +%% +clear B +try + B=BSM('type',3,'Acfl',[],'SPMs'); %#ok<*NASGU> %will create an error +catch ME + if strcmpi(ME.identifier,'BSM:getval:ReadBeyondEndInput') + disp('error properly handled') + disp(ME); + else + rethrow(ME); + end +end +%% +clear B +B=BSM('type',1,'Acfl',[],'SPMs',{}); +%% set SPMs validity check +B.SPMs=''; %should produce instructions on how to set SPMs +B.SPMs={'ui'}; %get input from the user +tmp=B.SPMs; %store for future use +%B.SPMs={'ui'}; %calling it again will allow me to edit the list +B.SPMs={}; %clear out SPMs +try + B.SPMs={'SPM.mat';'onzin.mat'}; %provides an error if file does not exist +catch ME + if strcmpi(ME.identifier,'BSM:SetSPMs:FileNotFound') + disp('error properly handled') + disp(ME); + else + rethrow(ME) + end +end +B.SPMs=tmp; +%% set Type check +try + B.Type='onzin'; %gives an error +catch ME + if strcmpi(ME.identifier,'BSM:Type:invalid') + disp('error properly handled') + disp(ME); + else + rethrow(ME) + end +end +%% +try + B.Type=0; %gives an error +catch ME + if strcmpi(ME.identifier,'BSM:Type:invalid') + disp('error properly handled') + disp(ME); + else + rethrow(ME) + end +end +%% +B.Type=1; % correct call +%% set Acfl check +try + B.Acfl=0; +catch ME + if strcmpi(ME.identifier,'BSM:Acfl:invalid') + disp('error properly handled') + disp(ME); + else + rethrow(ME) + end +end +%% +try + B.Acfl=-5; +catch ME + if strcmpi(ME.identifier,'BSM:Acfl:invalid') + disp('error properly handled') + disp(ME); + else + rethrow(ME) + end +end +%% +try + B.Acfl='test'; +catch ME + if strcmpi(ME.identifier,'BSM:Acfl:invalid') + disp('error properly handled') + disp(ME); + else + rethrow(ME) + end +end +%% +B.Acfl=[]; \ No newline at end of file