Home > fmri > utils > create_contrast_struct.m

create_contrast_struct

PURPOSE ^

[consess] = create_contrast_struct()

SYNOPSIS ^

function [consess] = create_contrast_struct(spmmat_fname,cinfo)

DESCRIPTION ^

 [consess] = create_contrast_struct()

 Utility function for populating the consess field of a job structure that is
 used by the SPM5 contrast manager

 Name of SPM.mat file to which the .Xcon structure will ultimately be added

 cinfo is a structure with fields
   .cont_name - the contrast name
   .cont_type - the contrast type (T,F)
   .incl_code - the conditions to include in the contrast

 Multiple contrasts are specified as multiple elements in a cinfo structure array

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SOURCE CODE ^

0001 function [consess] = create_contrast_struct(spmmat_fname,cinfo)
0002 % [consess] = create_contrast_struct()
0003 %
0004 % Utility function for populating the consess field of a job structure that is
0005 % used by the SPM5 contrast manager
0006 %
0007 % Name of SPM.mat file to which the .Xcon structure will ultimately be added
0008 %
0009 % cinfo is a structure with fields
0010 %   .cont_name - the contrast name
0011 %   .cont_type - the contrast type (T,F)
0012 %   .incl_code - the conditions to include in the contrast
0013 %
0014 % Multiple contrasts are specified as multiple elements in a cinfo structure array
0015 
0016 % 02/23/06  Petr Janata
0017 % 08/10/06  PJ - adapted from earlier version. Made cinfo to be a structure
0018 %                array rather than a single structure filled with cell arrays
0019 % 28Dec2014 PJ - added option of passing in an SPM structure instead of
0020 %                path to SPM.mat file
0021 %                Minor performance improvements per good coding practice
0022 % 29Aug2015 PJ - adapted to flexibly handle variable names as provided in
0023 %                SPM.xX.name or stripped out names.
0024 
0025 if ischar(spmmat_fname)
0026   if ~exist(spmmat_fname,'file')
0027     error('Could not locate SPM.mat file: %s',spmmat_fname)
0028   end
0029   
0030   %
0031   % Load information from the SPM.mat file about the regressors in the design matrix
0032   %
0033   load(spmmat_fname);
0034 elseif isstruct(spmmat_fname)
0035   % Handle case in which an SPM structure was passed in
0036   SPM = spmmat_fname;
0037 else
0038   error('spmmat_fname must be either a path to an SPM.mat file or an SPM structure')
0039 end
0040 cond_names_detail = SPM.xX.name;
0041 %Sess = SPM.Sess;
0042 clear SPM
0043 
0044 ncond = length(cond_names_detail);
0045 cond_names_stripped = cell(1,ncond);
0046 % Strip out the basic condition names that we want to match against
0047 for icond = 1:ncond
0048   condstr = cond_names_detail{icond};
0049   start_idx = find(isspace(condstr), 1 )+1;
0050   if isempty(start_idx)
0051     start_idx = 1;
0052   end
0053   stop_idx = min(regexp(condstr,'[\^*]'))-1; % Search for a caret and asterisk
0054   if isempty(stop_idx)
0055     stop_idx = length(condstr);
0056   end
0057   cond_names_stripped{icond} = condstr(start_idx:stop_idx);
0058 end
0059 
0060 % Initialize some variables
0061 ngood = 0;
0062 nc = length(cinfo); % Number of contrasts
0063 
0064 consess = {};
0065 
0066 % Loop over the list of contrasts
0067 for ic = 1:nc
0068   if isfield(cinfo,'use_orig_var_name')
0069     useOrigVarName = cinfo.use_orig_var_name;
0070   else
0071     useOrigVarName = false;
0072   end
0073   
0074   if useOrigVarName
0075     cond_names = cond_names_detail;
0076   else
0077     cond_names = cond_names_stripped;
0078   end
0079   
0080   cont_type = cinfo(ic).cont_type;
0081   cont_name = cinfo(ic).cont_name;
0082   incl_code = cinfo(ic).incl_code;
0083   switch cont_type
0084     case 'T'
0085 
0086       % First, try to grab the column index from the detailed list
0087       % This will pick up any regressors and condition components
0088       cond_a_mask = ismember(cond_names, incl_code{1});
0089       cond_b_mask = ismember(cond_names, incl_code{2});
0090       
0091       cond_a_vect = zeros(1, length(cond_names));
0092       cond_b_vect = zeros(1, length(cond_names));
0093       
0094       cond_a_vect(cond_a_mask) = 1;
0095       cond_b_vect(cond_b_mask) = 1;
0096       
0097       % Weight the contrasts appropriately, i.e. have sum=0
0098       suma = sum(cond_a_vect);
0099       sumb = sum(cond_b_vect);
0100       
0101       if suma && sumb
0102         ngood = ngood+1;
0103         weight_b = suma/sumb*-1;
0104         
0105         cond_b_vect = cond_b_vect * weight_b;
0106         
0107         convec = cond_a_vect + cond_b_vect;
0108       elseif suma
0109         %disp('Only numerator was specified in T contrast')
0110         ngood = ngood+1;
0111         convec = cond_a_vect;
0112       elseif sumb
0113         ngood = ngood+1;
0114         convec = cond_b_vect*-1;
0115       else
0116         fprintf('Skipping T contrast (%s): num_num: %d; num_denom: %d', cont_name,suma, sumb)
0117         continue
0118       end
0119       consess{ngood}.tcon.name = cont_name;
0120       consess{ngood}.tcon.convec = convec;
0121       
0122     case 'F'
0123       cols = zeros(1,length(cond_names));
0124       col_mask = ismember(cond_names, incl_code{1});      
0125       cols(col_mask) = 1;
0126       
0127       if any(cols)
0128         ngood = ngood+1;
0129         convec = full(sparse(1:sum(cols),find(cols),1));  % actually a matrix
0130         convec(end,length(cond_names)) = 0; % pad out with zeros
0131         consess{ngood}.fcon.name = cont_name;
0132         for irow = 1:size(convec,1)
0133           consess{ngood}.fcon.convec{irow} = num2str(convec(irow,:));
0134         end
0135       else
0136         fprintf('Skipping F contrast (%s)', cont_name)
0137         continue
0138       end
0139       
0140     otherwise
0141       error('Unknown contrast type: %s', cont_type)
0142       
0143   end % switch cont_type{ic}
0144   
0145 end % for ic
0146 
0147 return

Generated on Wed 20-Sep-2023 04:00:50 by m2html © 2003