fMRI_Connectivity/resources/BSM_Class/BSM.m

176 lines
6.5 KiB
Matlab

classdef BSM<handle
%BSM Summary of this class goes here
% Detailed explanation goes here
properties %public properties
SPMs={}; %field to contain the full path of all SPM.mat files to be analysed
Acfl %columns in SPM.xX.X to ignore
Type=1; %BSM type 1..4 5: none
end
properties %private properties
SPM_orig %temporary storage for SPM.mat file
ActiveColumns %store the columns to be analized
U_orig %store the U field of SPM
TargetFolder %target folder
% option below obsolete?
BSMToolboxPath%store path to BSMToolbox
SPMPath;%store path to SPM folder
SPMIndexList=[];
end
properties (Dependent) %dependent properties
NumSPMs% number of SPM.mat files to process
end
properties %constants
BSMMethod={'Traditional BSM Rissman et al', 'Adapted BSM Rissman et al', 'Fast approach (Mumford et al)', 'Adapted fast approach','none'};
end
methods %user callable methods
function Calc(obj,varargin)
% obj.calc to apply calculate to all SPM.mat files
% obj.calc(n) to calculated the nth SPM.mat file
% obj.calc([1 3 6]) to indicate which SPM.mat file to calculate
SPMidx=[];% will contain the index to the SPMs to work on
if logical(numel(varargin))
SPMidx=varargin{1};
end
%check number of input arguments
if ~logical(obj.NumSPMs)%nothing to do
fprintf('== == == Nothing to do: done == == ==\n')
return;
end
if isempty(SPMidx)
SPMidx=1:obj.NumSPMs;
end
if ~isnumeric(SPMidx)||~all(isfinite(SPMidx))||min(SPMidx)<1||max(SPMidx)>obj.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=<val>
%possible values for <val>
% {} : 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={<Ful path to SPM.mat>}');
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